前言:我代表一位朋友(显然是害羞地自己发布)发布此内容,我浏览了相关问题,但我似乎没有发现任何重复...但请注意我不要根本不懂Java,所以如果这是重复的话我会提前道歉!
这是代码的一部分:
public class ElencoEsami implements Comparable{
private ArrayList<EsameMedico> a = new ArrayList<EsameMedico>();
private Comparable comparatore;
public ElencoEsami() {
}
public void addEsame(EsameMedico e) {
if (a.isEmpty()) {
a.add(0,e);
return;
}
for(int i=0;i<a.size();i++) {
if (a.get(i).getData().after(e.getData())) {
a.add(i,e);
break;
}
}
a.add(e);
}
public int compareTo(Object o) {
// ?????
}
}
我的朋友希望实现“addEsame”,以便最大化代码可重用性,特别是他希望能够通过添加新类(比较器)来更改列表的排序方式(现在按名称排序)我相信哪个类?或者至少我会用C ++来做这件事。)
谢谢!
答案 0 :(得分:10)
首先,使用Collections.sort(List list,Comparator c)
然后,编码尽可能多的Comparator,因为您需要排序顺序
就是这样。
答案 1 :(得分:4)
通常,如果您希望能够使用比较器对列表重新排序,则不需要实现Comparable(仅适用于一个排序),您可以创建新的Comparator对象,这些对象可以写在该类之外并且可以指定任何可能的排序(由该类中的吸气者)
你需要的只是比较器的一个setter(该类中的一个字段),它在更改后对你的列表进行调整。
从另一个类看起来像:
your_object.setComparator(new Comparator<ElencoEsami>() {
public int compare(ElencoEsami o1, ElencoEsami o2) {
// do some comparing...
}
});
在你的课堂上,它看起来像是:
public void setComparator(Comparator<? extends ElencoEsami> comp) {
this.comparator = comp;
Collections.sort(this.listOfItems, comp);
}
答案 2 :(得分:3)
如果我想以可重用的方式实现多个比较器,我希望将它们实现为枚举(基于来自Old Tech Per的想法):
public class EsameMedico {
...
/** Enumeration of {@link Comparator}s for {@code EsameMedico}. */
public static enum Comparators implements Comparator<EsameMedico> {
/** Compares by name. */
BY_NAME {
public int compare(final EsameMedico em1, final EsameMedico em2) {
return em1.name.compareTo(em2.name);
}
public void sort(final List<EsameMedico> l) {
Collections.sort(l, BY_NAME);
}
},
/* Compares by whatever. */
BY_WHATEVER {
public int compare(final EsameMedico em1, final EsameMedico em2) {
return /* compare by "whatever" */;
}
public void sort(final List<EsameMedico> l) {
Collections.sort(l, BY_WHATEVER);
}
};
/** Sorts the list by this criterion. */
public abstract void sort(List<EsameMedico> l);
}
...
}
但请注意,对于列表,您必须自己在插入时维护列表的顺序。如果您希望自动对集合进行排序,SortedSet可能会有所帮助。 TreeSet是SortedSet
接口的一个实现,在其构造函数中使用Comparator
并对其元素进行排序。
答案 3 :(得分:2)
Sun在Java接口路径中有一个关于Object Ordering的页面。它简要概述了比较器以及如何编写它们。
答案 4 :(得分:1)
如果您想更改列表的顺序,可以使用Collections.sort()作为参数的comparator方法。
根据您的代码,您似乎在Comparable
和Comparator
接口之间存在一些混淆。实现Comparable
接口的类意味着它具有某种自然顺序(例如,Integer类基于它所代表的int自然排序)。使用比较器,您可以根据其他一些订购标准订购对象。
根据您发布的代码,我想询问您是否真的打算订购ElencoEsami课程,或者您是否打算订购EsameMedico对象?
如果是应该订购的EsameMedio类,那么应该实现Comparable接口的EsameMedico类。假设您在addEsame()方法中进行的比较是EsameMedico类的自然顺序,您可以在EsameMedico中实现compareTo()方法,如下所示:
public class EsameMedico implements Comparable<EsameMedico>{
...
public int compareTo(Object o) {
EsameMedico e = (EsameMedico)o;
if(getData().after(e.getData())) {
return 1;
} else if(e.getData().after(getData())){
return -1;
} else {
return 0;
}
}
}
然后,您可以将addEsame()方法更改为只需插入列表并在每次插入后调用Collections.sort()。当然,更好的方法是使用TreeSet而不是ArrayList。如果您这样做,每个EsameMedico将根据其自然顺序插入,您不必自己执行任何排序。
答案 5 :(得分:1)
如果您希望在使用addEsame
添加对象时对对象进行排序,而不调用Collections.sort()
,请使用带有要排序的密钥的TreeMap
。如果您的对象不同,请使用TreeSet
。
另一件事:
按照以下方式声明您的列表:
private List<EsameMedico> a;
(或Map
,Set
,无论您选择什么)
并在构造函数中初始化它:
a = new ArrayList<EsameMedico>();
(或TreeMap
...)
因为如果你扩展课程ElencoEsami
,你会得到一些奇怪的结果。
答案 6 :(得分:1)
答案 7 :(得分:0)
我发现这个例子非常有用: http://www.javabeat.net/tips/20-sorting-custom-types-in-java.html
对我而言,关键是Comparator类的一个例子:
package tips.sort;
import java.util.Comparator;
public class MovieComparator implements Comparator<Movie>{
@Override
public int compare(Movie movie1, Movie movie2) {
int rank1 = movie1.getRank();
int rank2 = movie2.getRank();
if (rank1 > rank2){
return +1;
}else if (rank1 < rank2){
return -1;
}else{
return 0;
}
}
}