2010-09-12 3 views
1

Я довольно новичок в Java, поэтому, вероятно, это довольно простой вопрос.Java, реализующий компаратор на ArrayList

Я хочу рассортировать ArrayList в классе MediaLib исходя из натурального порядка указанного ключа.

Не могу решить, как использовать мой компаратор (compareTo(MediaInterface, key)), который находится в классе Media. Каков наилучший способ сделать это?

package assign1; 

import java.util.*; 

public class Media implements MediaInterface { 

    private Map<String, Object> fields; 
    private static int compare; 

public Media(String title, String format) { 
    fields = new TreeMap<String, Object>(); 
    fields.put("title", title); 
    fields.put("format", format); 
} 


public Object get(String key) { 
    return fields.get(key); 
} 


public void put(String key, Object value) { 
    fields.put(key, value); 
} 


public boolean hasKeywords(String[] words, boolean combineWithAND) { 
    Collection<Object> values = (Collection<Object>) fields.values(); 
    int count = 0; 
    int size = 0; 
    for (String s: words) { 
     for (Object o: values) { 
       String t = o.toString(); 
       if (t.indexOf(s) >= 0) { 
        count++; 
        break; 
       } 
     } 
     size++; 
    } 
    if ((count == 0 && !combineWithAND) || (combineWithAND && (count != size))) { 
     return false; 
    } 
    return true; 
} 


public int compareTo(MediaInterface mi, String key) { //<<<<<<<------calling this!! 
    if (mi == null) 
    throw new NullPointerException(); 
    Media m = (Media) mi; 
    Comparable mValue = (Comparable) m.get(key); 
    Comparable lValue = (Comparable) fields.get(key); 
    if ((mValue == null) && (lValue == null)){ 
     return 0; 
    } 
    if ((lValue == null)){ 
      return 1; 
     } 
    if ((mValue == null)){ 
      return -1; 
     } 
    return (lValue).compareTo(mValue); 
} 


@Override 
public int compareTo(MediaInterface mi) { 
    if (mi == null) 
    throw new NullPointerException(); 
    Media m = (Media) mi; 
    Set<String> lSet = fields.keySet(); 
    if (compareTo(m, "title") != 0) { 
     return compareTo(m, "title"); 
    } 
    if (compareTo(m, "year") != 0) { 
      return compareTo(m, "year"); 
     } 
    for (String s: lSet) { 
     if (compareTo(m, s) != 0) { 
      return compareTo(m, s); 
     } 
    } 
    return 0; 
} 


public boolean equals(Object object) { 
    if (object == null) 
    return false; 
    if (!(object instanceof Media)) 
    return false; 
    Media m = (Media) object; 
    if (compareTo(m) != 0) { 
     return false; 
    } 
    return true; 
} 
} 

package assign1; 

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Collections; 
import java.util.Comparator; 

public class MediaLib implements Searchable { 
private ArrayList<MediaInterface> media; 

public MediaLib() { 
    media = new ArrayList<MediaInterface>(); 
} 


@Override 
public void add(MediaInterface mi) { 
    if (media.isEmpty()) { 
     media.add(mi); 
    } 
    else { 
     for (MediaInterface m: media) { 
      if (mi.equals(m)) { 
       return; 
      } 
     } 
     media.add(mi); 
    } 
} 


@Override 
public boolean contains(MediaInterface mi) { 
    for (MediaInterface m: media) { 
      if (mi.equals(m)) { 
       return true; 
      } 
     } 
    return false; 
} 


@Override 
public Collection<MediaInterface> findByKeyword(String[] words, boolean combineWithAND) { 
    Collection<MediaInterface> foundList = new ArrayList<MediaInterface>(); 
    for (MediaInterface mi: media) { 
     if (mi.hasKeywords(words, combineWithAND)) { 
      foundList.add(mi); 
     } 
    } 
    return foundList; 
} 


@Override 
public Collection<MediaInterface> findByTitle(String str) { 
    Collection<MediaInterface> foundList = new ArrayList<MediaInterface>(); 
     for (MediaInterface mi: media) { 
      if ((mi.get("title")).equals(str)) { 
       foundList.add(mi); 
      } 
     } 
     return foundList; 
} 


@Override 
public Collection<MediaInterface> getAllWithFormat(String formatName) { 
    Collection<MediaInterface> foundList = new ArrayList<MediaInterface>(); 
     for (MediaInterface mi: media) { 
      if ((mi.get("format")).equals(formatName)) { 
       foundList.add(mi); 
      } 
     } 
     return foundList; 
} 

public Collection<MediaInterface> getAll() { 
    Collection<MediaInterface> fullList = new ArrayList<MediaInterface>(); 
     for (MediaInterface mi: media) { 
      fullList.add(mi); 
     } 
     return fullList; 
} 


@Override 
public void removeAllWithKeyword(String[] words, boolean combineWithAND) { 
    Collection<MediaInterface> foundList = findByKeyword(words, combineWithAND); 
    for (MediaInterface mi: foundList) { 
     media.remove(mi); 
    } 
} 


@Override 
public void removeAllWithFormat(String format) { 
    Collection<MediaInterface> foundList = getAllWithFormat(format); 
     for (MediaInterface mi: foundList) { 
      media.remove(mi); 
     } 
} 


@Override 
public void sort() { 
    Collections.sort(media); 
} 


@Override 
public void sort(final String fieldName) { 
    Collections.sort(media, new Media.compareTo(MediaInterface, fieldName)) //<<<<<--------Trying to call compareTo() 

    } 
} 


public void parse(java.io.BufferedReader br) throws java.io.IOException { 
    while(br.readLine()!= null) { 
     Media mi = new Media(/n br.readLine(), br.readLine()); 
     while 

    } 
} 
} 
+1

ли MediaInterface реализует Сопоставимые? Кроме того, подпись метода compareTo неверна. Вот как это должно выглядеть: http://download.oracle.com/javase/tutorial/collections/interfaces/order.html – helpermethod

+0

Он должен сделать, чтобы аннотированный метод '@ Override' компилировал –

ответ

2

Вы уже реализуют интерфейс Comparable в вашем MediaInterface классе, это общий интерфейс, так что вы затем реализовать Comparable<MediaInterface>, который затем потребуется вам реализовать метод с подписью

public int compareTo(final MediaInterface other) 

Именно поэтому ваш звонок в Collections.sort(media); компилирует

Для сортировки по определенному имени поля вам необходимо предоставить экземпляр Comparator, самым простым способом будет создание внутреннего класса в вашем классе Media, который затем можно передать в Collections.sort. Например

public class Media implements MediaInterface { 
    public static final class FieldComparator implements Comparator<Media> { 
     private final String field; 

     public FieldComparator(final String field) { 
      this.field = field; 
     } 

     public int compare(final Media a, final Media b) { 
      // implementation to compare a.field to b.field 
     } 
    } 
} 

Вы можете переписать второй sort метод как

@Override 
public void sort(final String fieldName) { 
    Collections.sort(media, new Media.FieldComparator(fieldName)); 
} 
+0

спасибо Jon, я думал, что id нужно добавить что-то в медиа .... отлично работает, спасибо – Milk