簡介
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 版權聲明:本文爲博主原創文章,轉載請附上博文連接!