简介
Comparable和 Comparator都是java.util包下的两个接口,从字面上看这两个接口都是用来作比较用的,可是jdk里面不可能定义两个功能相同的接口,因此他们确定有不一样的用处。java
一、Comparable
1.1 说明
Comparable能够认为是一个内比较器,实现了Comparable接口的类有一个特色,就是这些 类是能够和本身比较的,至于具体和另外一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为天然比较方法。若是开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种状况:算法
1.2 举例
1.定义一个Girl.java类,实现Comparable接口,而且重写compareTo方法:默认比较的是当前Girl类,经过age属性进行比较。ide
public class Girl implements Comparable<Object> {测试
private String name;
private int age;this
public String getName() {
return name;
}spa
public void setName(String name) {
this.name = name;
}.net
public int getAge() {
return age;
}对象
public void setAge(int age) {
this.age = age;
}blog
public Girl(String name, int age) {
super();
this.name = name;
this.age = age;
}排序
@Override
public String toString() {
return "Girl [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
Girl g = (Girl)o;
return this.age - g.getAge();
}
}
2.定义测试类Test.java,定义一个ArrayList保存75个Girl,打乱顺序后(由于List自己是有序的),查看输出结果。代码以下:
public static void main(String[] args) {
List<Girl> list = new ArrayList<>(100);
Girl girl;
for (int i=0; i<75; i++) {
girl = new Girl("girl " + i, i);
list.add(girl);
}
Collections.shuffle(list);
list.stream().forEach(System.out::println);
}
输出结果:
Girl [name=girl 9, age=9]
Girl [name=girl 60, age=60]
Girl [name=girl 26, age=26]
Girl [name=girl 55, age=55]
Girl [name=girl 12, age=12]
Girl [name=girl 31, age=31]
Girl [name=girl 49, age=49]
Girl [name=girl 6, age=6]
…
输出是乱序的
三、仍是2中的方法,只不过添加一行代码:使用Collections的sort(T t)方法排序。
public static void main(String[] args) {
List<Girl> list = new ArrayList<>(100);
Girl girl;
for (int i=0; i<75; i++) {
girl = new Girl("girl " + i, i);
list.add(girl);
}
Collections.shuffle(list);
Collections.sort(list);
list.stream().forEach(System.out::println);
}
输出结果:
Girl [name=girl 0, age=0]
Girl [name=girl 1, age=1]
Girl [name=girl 2, age=2]
Girl [name=girl 3, age=3]
Girl [name=girl 4, age=4]
Girl [name=girl 5, age=5]
Girl [name=girl 6, age=6]
Girl [name=girl 7, age=7]
Girl [name=girl 8, age=8]
Girl [name=girl 9, age=9]
Girl [name=girl 10, age=10]
Girl [name=girl 11, age=11]
…
输出是有序的,而且是按compareTo方法中定义的根据age的升序比较。
二、Comparator
2.1 说明
Comparator能够认为是是一个外比较器,我的认为有两种状况可使用实现Comparator接口的方式:
一、一个对象不支持本身和本身比较(没有实现Comparable接口),可是又想对两个对象进行比较。
二、一个对象实现了Comparable接口,可是开发者认为compareTo方法中的比较方式并非本身想要的那种比较方式。
Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口同样是int,有三种状况:
一、o1大于o2,返回正整数
二、o1等于o2,返回0
三、o1小于o3,返回负整数
2.2 举例
1.定义一个Girl.java类以下:
public class Girl {
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 Girl(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Girl [name=" + name + ", age=" + age + "]";
}
}
2.定义GirlComparator.java类,实现Comparator接口,重写compare()方法,和前面同样根据age进行比较。
public class GirlComparator implements Comparator<Girl> {
@Override
public int compare(Girl g1, Girl g2) {
return g1.getAge() - g2.getAge();
}
}
2.定义测试类Test.java,定义一个TreeSet保存75个Girl,查看输出结果。代码以下:
public static void main(String[] args) {
Set<Girl> set = new TreeSet<>();
Girl girl;
for (int i = 0; i< 75; i++) {
girl = new Girl("girl "+i, i);
set.add(girl);
}
set.stream().forEach(System.out::println);
}
输出结果:
Girl [name=girl 0, age=0]
Girl [name=girl 1, age=1]
Girl [name=girl 2, age=2]
Girl [name=girl 3, age=3]
Girl [name=girl 4, age=4]
Girl [name=girl 5, age=5]
Girl [name=girl 6, age=6]
Girl [name=girl 7, age=7]
Girl [name=girl 8, age=8]
Girl [name=girl 9, age=9]
Girl [name=girl 10, age=10]
Girl [name=girl 11, age=11]
Girl [name=girl 12, age=12]
…
输出是有序的,而且是按compare方法中定义的根据age的升序比较。
三、总结
总结一下,这两种比较器Comparable和Comparator,后者相比前者有以下优势:
个性化比较:若是实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,可是对compareTo方法内的比较算法不满意),那么能够实现Comparator接口,自定义一个比较器,写比较算法。解耦:实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,若是要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不须要对实现类有任何修改。从这个角度说,其实有些不太好,尤为在咱们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。--------------------- 做者:Tony.Wu 来源:CSDN 原文:https://blog.csdn.net/wlh2015/article/details/83959462 版权声明:本文为博主原创文章,转载请附上博文连接!