1. 相同点:
他们都是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 如果想排序, 也要实现一个比较器。
2. 区别
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]]
3.总结
两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码, 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。