一文搞清楚Java中Comparable和Comparator的區(qū)別
Java中的Comparable
和Comparator
都是用于集合排序的接口,但它們有明顯的區(qū)別。
很多人問我,到底該用哪一個,自己在使用時很疑惑?
對于這個問題,沒有一定的規(guī)則來決定選擇哪一個更好,因?yàn)樗Q于具體情況以及開發(fā)者的個人偏好。
如果你所需要排序的類已經(jīng)實(shí)現(xiàn)了
Comparable
接口,那么你可以直接使用該類默認(rèn)的比較規(guī)則進(jìn)行排序。否則,你可以考慮實(shí)現(xiàn)一個或多個Comparator
接口,并基于不同的比較規(guī)則對同一個類進(jìn)行排序。在某些情況下,你可能會發(fā)現(xiàn)自己需要對同一個類使用多個不同的比較規(guī)則進(jìn)行排序。在這種情況下,使用
Comparator
接口是一種更加靈活的選擇,因?yàn)槟憧梢愿鶕?jù)需要編寫任意數(shù)量的比較器,并將它們與同一個類的不同實(shí)例一起使用。在另一些情況下,你可能會發(fā)現(xiàn)自然排序已經(jīng)足夠滿足你的需求。如果你只需要對一個類中的對象按照默認(rèn)的比較規(guī)則進(jìn)行排序,那么你可以直接實(shí)現(xiàn)
Comparable
接口。
在本文詳細(xì)介紹兩者前,我申明,在Java中,Comparable
和Comparator
都是非常有用的接口,能夠幫助開發(fā)者輕松地對集合進(jìn)行排序,并根據(jù)特定的比較規(guī)則來確定排序順序。具體選擇哪一個接口,需要考慮多方面的因素,并且也要結(jié)合具體的需求和實(shí)際情況來進(jìn)行選擇。
1、Comparable
Comparable
是一個排序接口,它強(qiáng)制實(shí)現(xiàn)排序規(guī)則在類本身定義,也就是說,如果一個類實(shí)現(xiàn)了Comparable
接口,那么該類的對象就可以進(jìn)行自然排序。自然排序即默認(rèn)排序,如數(shù)字的升序排序、字符串的字典序排序等。
實(shí)現(xiàn)Comparable
需要重寫其中的compareTo
方法,該方法的返回值類型為int,根據(jù)比較結(jié)果返回正整數(shù)、0或者負(fù)整數(shù),其含義如下:
- 返回正整數(shù):當(dāng)前對象大于目標(biāo)對象
- 返回0:當(dāng)前對象等于目標(biāo)對象
- 返回負(fù)整數(shù):當(dāng)前對象小于目標(biāo)對象
以下代碼示例展示了如何實(shí)現(xiàn)Comparable
接口:
public class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Person o) { return this.age - o.age; } // 省略getter/setter方法 }
在上述代碼中,Person
類實(shí)現(xiàn)了Comparable
接口,并重寫了其中的compareTo
方法,按照年齡大小進(jìn)行比較。這里的比較規(guī)則是年齡越小,優(yōu)先級越高。
使用Comparable
進(jìn)行排序時,只需要對集合調(diào)用Collections.sort()
方法,因?yàn)樵摲椒ㄒ呀?jīng)內(nèi)置了對自然排序的支持。
List<Person> personList = new ArrayList<>(); personList.add(new Person("張三", 20)); personList.add(new Person("李四", 18)); personList.add(new Person("王五", 21)); Collections.sort(personList); System.out.println(personList);
運(yùn)行上述代碼,結(jié)果如下所示:
[Person{name='李四', age=18}, Person{name='張三', age=20}, Person{name='王五', age=21}]
2、Comparator
Comparator
是一個比較器接口,它可以為需要排序的類提供多種不同的排序規(guī)則。與Comparable
不同的是,Comparator
實(shí)現(xiàn)的排序規(guī)則是在調(diào)用時才確定。
同樣需要重寫其中的compare
方法,在方法中傳入兩個待比較的對象,并返回比較結(jié)果,含義和compareTo
方法相同。但是,需要注意的是,對于同一類型的不同對象,不同的比較器實(shí)現(xiàn)可能會返回不同的比較結(jié)果。
以下代碼示例展示了如何使用Comparator
進(jìn)行排序:
public class PersonAgeComparator implements Comparator<Person> { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } } List<Person> personList = new ArrayList<>(); personList.add(new Person("張三", 20)); personList.add(new Person("李四", 18)); personList.add(new Person("王五", 21)); Collections.sort(personList, new PersonAgeComparator()); System.out.println(personList);
在上述代碼中,我們實(shí)現(xiàn)了一個PersonAgeComparator
比較器,按照年齡大小進(jìn)行比較。在調(diào)用Collections.sort()
方法時,傳入該比較器作為參數(shù),即可按照指定的規(guī)則進(jìn)行排序。
運(yùn)行上述代碼,結(jié)果如下所示:
[Person{name='李四', age=18}, Person{name='張三', age=20}, Person{name='王五', age=21}]
除此之外,我們還可以使用lambda表達(dá)式來簡化比較器的實(shí)現(xiàn):
Collections.sort(personList, (o1, o2) -> o1.getAge() - o2.getAge());
3、Comparable和Comparator的區(qū)別
Comparable是內(nèi)部比較器,而Comparator是外部比較器。實(shí)現(xiàn)Comparable的類,在其內(nèi)部定義了比較規(guī)則;而使用Comparator時,則需要單獨(dú)定義一個外部比較器。
Comparable的排序規(guī)則是固定的,不可更改;而Comparator的排序規(guī)則是可以根據(jù)需要自己定義的。
Comparable的排序規(guī)則只適用于該類的對象,而Comparator的排序規(guī)則可以適用于不同類型的對象。
當(dāng)我們需要對自定義類型進(jìn)行排序時,如果實(shí)現(xiàn)了Comparable接口,就意味著該類型具有了默認(rèn)的排序規(guī)則;如果沒有實(shí)現(xiàn)Comparable接口,則需要單獨(dú)定義Comparator。
總的來說,Comparable和Comparator都是Java中用于集合排序的接口,但它們有各自的優(yōu)缺點(diǎn)。在實(shí)際編程中,我們需要根據(jù)具體情況選擇使用哪種方式,才能更加高效地完成任務(wù)。
以上就是一文搞清楚Java中Comparable和Comparator的區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于Java Comparable和Comparator區(qū)別的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
深入探究MyBatis插件機(jī)制靈活擴(kuò)展及自定義增強(qiáng)框架能力
這篇文章主要介紹了深入探究MyBatis插件機(jī)制靈活擴(kuò)展及自定義增強(qiáng)框架能力2024-01-01java使用hadoop實(shí)現(xiàn)關(guān)聯(lián)商品統(tǒng)計(jì)
本篇文章java使用hadoop實(shí)現(xiàn)關(guān)聯(lián)商品統(tǒng)計(jì),可以實(shí)現(xiàn)商品的關(guān)聯(lián)統(tǒng)計(jì),具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-10-10IDEA 中使用 ECJ 編譯出現(xiàn) java.lang.IllegalArgumentException的錯誤問題
這篇文章主要介紹了IDEA 中使用 ECJ 編譯出現(xiàn) java.lang.IllegalArgumentException問題 ,本文內(nèi)容簡短給大家介紹的好,需要的朋友可以參考下2020-05-05Spring Boot實(shí)現(xiàn)郵件發(fā)送必會的5種姿勢
這篇文章主要給大家介紹了關(guān)于Spring Boot實(shí)現(xiàn)郵件發(fā)送必會的5種姿勢,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07