面試官:問下基礎(chǔ),你能說說Java中Comparable和Comparator的區(qū)別嗎
之前面試中被問到這個問題,當(dāng)時不屑(會)回答,下來特意查了查,整理如下。
Java 中為我們提供了兩種比較機制:Comparable 和 Comparator,二者都是用來實現(xiàn)對象的比較、排序。
下面分別對Comparable 和 Comparator做具體介紹并總結(jié)。
Comparable
Comparable可以認(rèn)為是一個內(nèi)比較器,實現(xiàn)了Comparable接口的類有一個特點,就是這些類是可以和自己比較的,至于具體和另一個實現(xiàn)了Comparable接口的類如何比較,則依賴compareTo方法的實現(xiàn)。
如果add進入一個Collection的對象想要Collections的sort方法幫你自動進行排序的話,那么這個對象必須實現(xiàn)Comparable接口。compareTo方法的返回值是int,有三種情況:
比較者大于被比較者,返回正整數(shù)
比較者等于被比較者,返回0
比較者小于被比較者,返回負(fù)整數(shù)
寫個很簡單的例子:
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));
}
運行結(jié)果為:
0
1
-1
注意一下,前面說實現(xiàn)Comparable接口的類是可以支持和自己比較的,但是其實代碼里面Comparable的泛型未必就一定要是Domain,將泛型指定為String或者指定為其他任何任何類型都可以,只要開發(fā)者指定了具體的比較算法就行。
Comparator
Comparator接口里面有一個compare方法,方法有兩個參數(shù)T o1和T o2,是泛型的表示方式,分別表示待比較的兩個對象,方法返回值和Comparable接口一樣是int,有三種情況:
o1大于o2,返回正整數(shù)
o1等于o2,返回0
o1小于o3,返回負(fù)整數(shù)
寫個很簡單的例子:
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));
}
看一下運行結(jié)果:
0
1
-1
因為泛型指定死了,所以實現(xiàn)Comparator接口的實現(xiàn)類只能是兩個相同的對象(不能一個Domain、一個String)進行比較了,實現(xiàn)Comparator接口的實現(xiàn)類一般都會以"待比較的實體類+Comparator"來命名
總結(jié)
如果實現(xiàn)類沒有實現(xiàn)Comparable接口,又想對兩個類進行比較(或者實現(xiàn)類實現(xiàn)了Comparable接口,但是對compareTo方法內(nèi)的比較算法不滿意),那么可以實現(xiàn)Comparator接口,自定義一個比較器,寫比較算法。
實現(xiàn)Comparable接口的方式比實現(xiàn)Comparator接口的耦合性要強一些,如果要修改比較算法,要修改Comparable接口的實現(xiàn)類,而實現(xiàn)Comparator的類是在外部進行比較的,不需要對實現(xiàn)類有任何修改。因此:
對于一些普通的數(shù)據(jù)類型(比如 String, Integer, Double…),它們默認(rèn)實現(xiàn)了Comparable 接口,實現(xiàn)了 compareTo 方法,我們可以直接使用。
而對于一些自定義類,它們可能在不同情況下需要實現(xiàn)不同的比較策略,我們可以新創(chuàng)建 Comparator 接口,然后使用特定的 Comparator 實現(xiàn)進行比較。
不同之處:
個人感覺說出上文觀點,這個提問就算回答完了,如果非要說不同之處,那就是:
Comparator位于java.util包下,而Comparable位于java.lang包下
實現(xiàn)Comparable接口的方式比實現(xiàn)Comparator接口的耦合性要強
等等………..
往期資源 需要請自取
往期資源 需要請自取
喜歡就"在看"唄^_^
