以前面試中被問到這個問題,當時不屑(會)回答,下來特地查了查,整理以下。java
Java 中爲咱們提供了兩種比較機制:Comparable 和 Comparator,兩者都是用來實現對象的比較、排序。面試
下面分別對Comparable 和 Comparator作具體介紹並總結。算法
Comparable能夠認爲是一個內比較器,實現了Comparable接口的類有一個特色,就是這些類是能夠和本身比較的,至於具體和另外一個實現了Comparable接口的類如何比較,則依賴compareTo方法的實現。dom
若是add進入一個Collection的對象想要Collections的sort方法幫你自動進行排序的話,那麼這個對象必須實現Comparable接口。compareTo方法的返回值是int,有三種狀況:this
比較者大於被比較者,返回正整數spa
比較者等於被比較者,返回0code
比較者小於被比較者,返回負整數對象
寫個很簡單的例子:blog
public class Domain implements Comparable<Domain> { private String str; public Domain(String str) { this.str = str; } public int compareTo(Domain domain) { if (this.str.compareTo(domain.str) > 0) return 1; else if (this.str.compareTo(domain.str) == 0) return 0; else return -1; } public String getStr() { return str; } }
public static void main(String[] args) { Domain d1 = new Domain("c"); Domain d2 = new Domain("c"); Domain d3 = new Domain("b"); Domain d4 = new Domain("d"); System.out.println(d1.compareTo(d2)); System.out.println(d1.compareTo(d3)); System.out.println(d1.compareTo(d4)); }
運行結果爲:排序
0
1
-1
注意一下,前面說實現Comparable接口的類是能夠支持和本身比較的,可是其實代碼裏面Comparable的泛型未必就必定要是Domain,將泛型指定爲String或者指定爲其餘任何任何類型均可以,只要開發者指定了具體的比較算法就行。
Comparator接口裏面有一個compare方法,方法有兩個參數T o1和T o2,是泛型的表示方式,分別表示待比較的兩個對象,方法返回值和Comparable接口同樣是int,有三種狀況:
o1大於o2,返回正整數
o1等於o2,返回0
o1小於o3,返回負整數
寫個很簡單的例子:
public class DomainComparator implements Comparator<Domain> { public int compare(Domain domain1, Domain domain2) { if (domain1.getStr().compareTo(domain2.getStr()) > 0) return 1; else if (domain1.getStr().compareTo(domain2.getStr()) == 0) return 0; else return -1; } }
public static void main(String[] args) { Domain d1 = new Domain("c"); Domain d2 = new Domain("c"); Domain d3 = new Domain("b"); Domain d4 = new Domain("d"); DomainComparator dc = new DomainComparator(); System.out.println(dc.compare(d1, d2)); System.out.println(dc.compare(d1, d3)); System.out.println(dc.compare(d1, d4)); }
看一下運行結果:
0
1
-1
由於泛型指定死了,因此實現Comparator接口的實現類只能是兩個相同的對象(不能一個Domain、一個String)進行比較了,實現Comparator接口的實現類通常都會以"待比較的實體類+Comparator"來命名
若是實現類沒有實現Comparable接口,又想對兩個類進行比較(或者實現類實現了Comparable接口,可是對compareTo方法內的比較算法不滿意),那麼能夠實現Comparator接口,自定義一個比較器,寫比較算法。
實現Comparable接口的方式比實現Comparator接口的耦合性要強一些,若是要修改比較算法,要修改Comparable接口的實現類,而實現Comparator的類是在外部進行比較的,不須要對實現類有任何修改。所以:
對於一些普通的數據類型(好比 String, Integer, Double…),它們默認實現了Comparable 接口,實現了 compareTo 方法,咱們能夠直接使用。
而對於一些自定義類,它們可能在不一樣狀況下須要實現不一樣的比較策略,咱們能夠新建立 Comparator 接口,而後使用特定的 Comparator 實現進行比較。
不一樣之處:
我的感受說出上文觀點,這個提問就算回答完了,若是非要說不一樣之處,那就是:
Comparator位於java.util包下,而Comparable位於java.lang包下
實現Comparable接口的方式比實現Comparator接口的耦合性要強
等等………..