2

前言:我代表一个朋友发这个(他显然很害羞自己发),我浏览了相关的问题,我似乎没有找到任何重复的..但请注意我不知道完全是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++ 中这样做)。

谢谢!

4

7 回答 7

10

首先,使用 Collections.sort(List list, Comparator c)

然后,根据需要编写尽可能多的 Comparator 排序顺序

就是这样。

于 2009-11-06T15:56:21.100 回答
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可能会有所帮助。TreeSetSortedSet是接口的一个实现,Comparator在其构造函数中接受 a 并自行对其元素进行排序。

于 2009-11-06T16:16:44.130 回答
2

Sun 在 Java 接口跟踪中有一个关于Object Ordering的页面。它简要概述了比较器以及如何编写它们。

于 2009-11-06T16:06:30.453 回答
1

如果要更改列表的顺序,可以使用Collections.sort()方法,该方法将比较器作为参数。

根据您的代码,您似乎在ComparableComparator接口之间存在一些混淆。实现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 将根据其自然顺序插入,您不必自己执行任何排序。

于 2009-11-06T15:58:03.843 回答
1

如果您想在添加对象时对其进行排序addEsame,而不调用Collections.sort(),请使用 aTreeMap和您想要排序的键。如果您的对象不同,请使用TreeSet.

还有一件事:

像这样声明你的列表:

private List<EsameMedico> a;

(或者Map,,Set无论你选择什么)

并在构造函数中初始化它:

a = new ArrayList<EsameMedico>();

(或者TreeMap……)

因为如果你扩展这个类ElencoEsami,你会得到一些奇怪的结果。

于 2009-11-06T16:18:52.820 回答
1
  1. 使用排序方法而不是“手工排序”;
  2. 正如 twolfe18 所指出的,使用 Comparator 对象,并仔细查看Strategy 设计模式
于 2009-11-06T16:29:05.437 回答
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;
    }
}

}

于 2012-03-11T12:13:31.130 回答