他们都是java的一个接口, 并且是用来对自定义的class比较大小的, 什么是自定义class: 如 public class Person{ String name; int age }. 当我们有这么一个personList,里面包含了person1, person2, persion3....., 我们用Collections.sort( personList ), 是得不到预期的结果的. 这时肯定有人要问, 那为什么可以排序一个字符串list呢: 如 StringList{"hello1" , "hello3" , "hello2"}, Collections.sort( stringList ) 能够得到正确的排序, 那是因为 String 这个对象已经帮我们实现了 Comparable接口 , 所以我们的 Person 如果想排序, 也要实现一个比较器。
Comparable定义在类的内部,
public class Man implements Comparable<Man>{ ..... } 因为已经实现了比较器,那么我们的Person现在是一个可以比较大小的对象了,它的比较功能和String完全一样,可以随时随地的拿来 比较大小,因为Person现在自身就是有大小之分的。Collections.sort(personList)可以得到正确的结果。public class Man implements Comparable<Man>{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Man(String name,int age){ this.age=age; this.name=name; } //按照年龄升序,年龄一致则按照姓名升序 @Override public int compareTo(Man o) { int i=age-o.getAge(); if(i==0){ i = name.compareTo(o.getName()); } return i; } @Override public String toString() { return "Man [name=" + name + ", age=" + age + "]"; } } Man man1 = new Man("a",1); Man man2 = new Man("a",2); Man man3 = new Man("b",1); Man man4 = new Man("c",3); Set<Man> map = new TreeSet<Man>(); map.add(man1); map.add(man2); map.add(man3); map.add(man4); Iterator<Man> it = map.iterator(); while(it.hasNext()){ System.out.println(it.next()); } 输出:
Man [name=a, age=1] Man [name=b, age=1] Man [name=a, age=2] Man [name=c, age=3]
Comparator定义在类的外部,原类结构不需要有任何变化
public class Woman { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Woman(String name,int age){ this.age=age; this.name=name; } @Override public String toString() { return "Woman [name=" + name + ", age=" + age + "]"; } } 实现接口类 public class WomanCompartor implements Comparator<Woman>{ @Override public int compare(Woman o1, Woman o2) { int i=o1.getAge()-o2.getAge(); if(i==0){ i =o1.getName().compareTo(o2.getName()); } return i; } } 比较 List<Woman> list = new ArrayList<Woman>(); Woman w1 = new Woman("a", 1); Woman w2 = new Woman("a", 2); Woman w3 = new Woman("b", 1); Woman w4 = new Woman("c", 3); list.add(w1); list.add(w2); list.add(w3); list.add(w4); Collections.sort(list, new WomanCompartor()); System.out.println(list); 结果: [Woman [name=a, age=1], Woman [name=b, age=1], Woman [name=a, age=2], Woman [name=c, age=3]]两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码, 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。