Java Comparable及Comparator接口區(qū)別詳解
在實(shí)際應(yīng)用中,我們往往有需要比較兩個(gè)自定義對(duì)象大小的地方。而這些自定義對(duì)象的比較,就不像簡(jiǎn)單的整型數(shù)據(jù)那么簡(jiǎn)單,它們往往包含有許多的屬性,我們一般都是根據(jù)這些屬性對(duì)自定義對(duì)象進(jìn)行比較的。所以Java中要比較對(duì)象的大小或者要對(duì)對(duì)象的集合進(jìn)行排序,需要通過(guò)比較這些對(duì)象的某些屬性的大小來(lái)確定它們之間的大小關(guān)系。
一般,Java中通過(guò)接口實(shí)現(xiàn)兩個(gè)對(duì)象的比較,比較常用就是Comparable接口和Comparator接口。首先類(lèi)要實(shí)現(xiàn)接口,并且使用泛型規(guī)定要進(jìn)行比較的對(duì)象所屬的類(lèi),然后類(lèi)實(shí)現(xiàn)了接口后,還需要實(shí)現(xiàn)接口定義的比較方法(compareTo方法或者compare方法),在這些方法中傳入需要比較大小的另一個(gè)對(duì)象,通過(guò)選定的成員變量與之比較,如果大于則返回1,小于返回-1,相等返回0。
一般簡(jiǎn)單的回答可以這么說(shuō):
1)首先這兩個(gè)接口一般都是用來(lái)實(shí)現(xiàn)集合內(nèi)的排序,comparable還可以用于兩個(gè)對(duì)象大小的比較。
2)Comparable接口在java.lang包下面。里面有一個(gè)compareTo(T)接口方法。當(dāng)一個(gè)類(lèi)需要比較的時(shí)候,需自行實(shí)現(xiàn)Comparable接口的CompareTo方法。當(dāng)調(diào)用集合排序方法的時(shí)候,就會(huì)調(diào)用對(duì)象的compareTo()方法來(lái)實(shí)現(xiàn)對(duì)象的比較。
3)Comparator接口在java.util包下面。Comparator是一個(gè)比較器接口,一般單獨(dú)定義一個(gè)比較器實(shí)現(xiàn)該接口中的比較方法compare();在集合sort方法中傳入對(duì)應(yīng)的比較器實(shí)現(xiàn)類(lèi)。一般使用匿名內(nèi)部類(lèi)來(lái)實(shí)現(xiàn)比較器。
4)Comparator相對(duì)于Comparable來(lái)說(shuō)更加的靈活,耦合度低。
首先呢,我們可以先了解一下List是如何排序的,我通過(guò)寫(xiě)一個(gè)例子來(lái)說(shuō)明;
先寫(xiě)一個(gè)實(shí)體類(lèi);
public class User { private String name; private Integer age; public static void main(String[] args) { List<User> users=new ArrayList<>(); users.add(new User("yao",19)); users.add(new User("zhang",20)); users.add(new User("li",17)); users.add(new User("xu",15)); users.add(new User("xupeng",15)); users.sort(new UserComparator()); System.out.println(users); } public User(){ } public User(String name, Integer age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
再寫(xiě)一個(gè)實(shí)現(xiàn)比較器接口的類(lèi)方法;
/** * 實(shí)現(xiàn)比較器接口,并重寫(xiě)compare方法 */ public class UserComparator implements Comparator<User> { @Override public int compare(User o1, User o2) { int age=o1.getAge()- o2.getAge(); return age!=0?age:o1.getName().length()-o2.getName().length(); } }
最后,我們的測(cè)試結(jié)果是這樣的,說(shuō)明成功了;
一、Comparable接口
1)什么是Comparable接口:
此接口強(qiáng)行對(duì)實(shí)現(xiàn)它的每個(gè)類(lèi)的對(duì)象進(jìn)行整體排序。此排序被稱為該類(lèi)的自然排序 ,類(lèi)的 compareTo方法被稱為它的自然比較方法 。實(shí)現(xiàn)此接口的對(duì)象列表(和數(shù)組)可以通過(guò) Collections.sort(和 Arrays.sort )進(jìn)行自動(dòng)排序。實(shí)現(xiàn)此接口的對(duì)象可以用作有序映射表中的鍵或有序集合中的元素,無(wú)需指定比較器。
2)實(shí)現(xiàn)什么方法:
int compareTo(T o)
比較此對(duì)象與指定對(duì)象的順序。如果該對(duì)象小于、等于或大于指定對(duì)象,則分別返回負(fù)整數(shù)、零或正整數(shù)。
參數(shù): o - 要比較的對(duì)象。
返回:負(fù)整數(shù)、零或正整數(shù),根據(jù)此對(duì)象是小于、等于還是大于指定對(duì)象。
拋出:ClassCastException - 如果指定對(duì)象的類(lèi)型不允許它與此對(duì)象進(jìn)行比較。
3)實(shí)例(注:代碼基本上只改動(dòng)我圈出來(lái)的即可測(cè)試,其它的照List排序的元代碼使用即可測(cè)試出結(jié)果):
當(dāng)前對(duì)象 this與傳入的其他對(duì)應(yīng)的比較方法時(shí);
二、Comparator接口
1)實(shí)例說(shuō)明:
Comparator接口與Comparable接口不同的是:
①Comparator位于包java.util下,而Comparable位于包java.lang下。
②Comparable接口將比較代碼嵌入需要進(jìn)行比較的類(lèi)的自身代碼中,而Comparator接口在一個(gè)獨(dú)立的類(lèi)中實(shí)現(xiàn)比較。
③comparator接口相對(duì)更靈活些,因?yàn)樗涌趯?shí)現(xiàn)的類(lèi)是耦合在一起的,可以通過(guò)換比較器來(lái)?yè)Q不同的規(guī)則進(jìn)行比較,即如果前期類(lèi)的設(shè)計(jì)沒(méi)有考慮到類(lèi)的Compare問(wèn)題而沒(méi)有實(shí)現(xiàn)Comparable接口,后期可
以通過(guò)Comparator接口來(lái)實(shí)現(xiàn)比較算法進(jìn)行排序,并且為了使用不同的排序標(biāo)準(zhǔn)做準(zhǔn)備,比如:升序、降序。
④Comparable接口強(qiáng)制進(jìn)行自然排序,而Comparator接口不強(qiáng)制進(jìn)行自然排序,可以指定排序順序。
⑤換一種說(shuō)法,簡(jiǎn)單的說(shuō):
Comparable:使user類(lèi)具有自比較的能力,可以讓自己跟同類(lèi)型的數(shù)據(jù)做比較;
Comparator:就是一個(gè)比較器,像一個(gè)第三方,傳入兩個(gè)對(duì)象,讓比較器去判斷誰(shuí)大誰(shuí)?。?/p>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java 8中map()和flatMap()方法區(qū)別詳解
這篇文章主要為大家介紹了Java 8中map()和flatMap()方法區(qū)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07spring boot 監(jiān)控處理方案實(shí)例詳解
這篇文章主要介紹了spring boot 監(jiān)控處理方案的相關(guān)資料,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07關(guān)于java的包Package中同名類(lèi)的沖突及其理解
這篇文章主要介紹了關(guān)于java的包Package中同名類(lèi)的沖突及其理解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08Mybatis查找返回Map,List集合類(lèi)型的數(shù)據(jù)方式
這篇文章主要介紹了Mybatis查找返回Map,List集合類(lèi)型的數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java中File、Base64、MultipartFile之間相互轉(zhuǎn)換的代碼詳解
File、Base64和MultipartFile都是在編程中常用的類(lèi)或者數(shù)據(jù)類(lèi)型,用于處理文件和數(shù)據(jù)的存儲(chǔ)、傳輸和轉(zhuǎn)換等操作,本文將給大家介紹了Java中File、Base64、MultipartFile之間相互轉(zhuǎn)換,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2024-04-04詳解Spring cloud使用Ribbon進(jìn)行Restful請(qǐng)求
這篇文章主要介紹了詳解Spring cloud使用Ribbon進(jìn)行Restful請(qǐng)求,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04