Java基礎(chǔ)語(yǔ)法之對(duì)象的比較方式
1. 引入
基本類型可以直接比較大小,但是我們自定義的類類型可能就無(wú)法比較,如果自定義類的類型本身有多個(gè)屬性的話,那么是以什么樣的方式去比較這個(gè)類型對(duì)象的大小呢?
對(duì)于上述自定義的類類型的比較大小,我們有以下三種處理方式:
- 覆蓋基類的 equals 方法
- 基于 Comparable 接口類的比較
- 基于比較器比較
2. 方法一:覆寫基類的 equals
2.1 介紹
對(duì)于自定義的類型,都默認(rèn)繼承了 Object 類,而 Object 類中提供了 equals 方法。
故我們可以使用 equals 方法去判斷兩個(gè)對(duì)象是不是相等。但是并不是任何情況都適用,下面為 Object 類中 equals 方法的定義

我們知道對(duì)于引用類型,用 == 號(hào)比較的其實(shí)是引用變量的地址,所以即使兩個(gè)對(duì)象的值相等,但是由于地址不同所以結(jié)果也可能是錯(cuò)的,并且還由于自定義類中的屬性不為1,所以不重寫基類的 equals 方法的話,是無(wú)法正確比較對(duì)象的。
2.2 覆寫 equals 方法的規(guī)則
- 如果指向同一個(gè)對(duì)象,則返回 true
- 如果傳入的值為 null,則返回 false
- 如果傳入的對(duì)象類型不是自定義類或其子類,則返回 false
- 最后比較對(duì)象的各個(gè)屬性,如果是基本類型,則可以直接用 == 比較;如果是引用類型,則使用 equals 方法比較
2.3 實(shí)現(xiàn)代碼
以下用自定義的 Student 類為例,重寫其基類的 equals 方法
class Student{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o){
if(this==o){
return true;
}
if(o==null || !(o instanceof Student)){
return false;
}
Student c=(Student)o;
return this.name.equals(c.name) && this.age==c.age;
}
}
2.4 局限性
覆寫基類 equals 的方法雖然可以使自定義的類被比較,但是該方法只能進(jìn)行相等和不相等的比較,不能按照大于或小于的方式進(jìn)行比較。
3. 方法二:基于 Comparable 接口的比較
3.1 介紹
該方法在 解析 Java 的多態(tài)、抽象類和接口 這章介紹過了,有興趣了解的 uu 可以去那篇文章里面看看
注意:
Comparable 是 java.lang 中的接口類,可以直接使用。
3.2 使用方法
- 先讓自定義的類繼承 Comparable 接口
- 再根據(jù)我們要以自定義類的哪個(gè)屬性去比較,來重寫 Comparable 類中的 compareTo 方法
3.3 實(shí)現(xiàn)代碼
以下用自定義的 Student 類為例,以 name 為我們要比較的屬性
class Student implements Comparable<Student>{
publice String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o){
return this.name.compareTo(o.name);
}
}
3.4 局限性
該方法雖然可以讓不同對(duì)象根據(jù)某一個(gè)屬性來比較大小,但是當(dāng)我們確定好了以哪一個(gè)屬性來比較對(duì)象的話,那么當(dāng)我們想要使用另一個(gè)屬性比較對(duì)象時(shí),則需要修改重寫 compareTo 方法
4. 方法三:基于 Comparator 接口,自定義比較器的比較
4.1 介紹
該方法在 解析 Java 的多態(tài)、抽象類和接口 這章介紹過了,有興趣了解的 uu 可以去那篇文章里面看看
注意:
Comparator 是 java.util 包中的泛型接口類,使用時(shí)必須導(dǎo)入對(duì)應(yīng)的包。
4.2 使用方法
- 我們選擇一個(gè)自定義類中要比較的屬性,可以再定義一個(gè)類(即比較器),繼承于 Comparator 接口
- 在該接口中,重寫 Comparator 接口的 compare 方法,該方法重寫的就是對(duì)這個(gè)屬性比較的規(guī)則
- 使用時(shí)我們就使用 compare 方法,
4.3 實(shí)現(xiàn)代碼
以下用自定義的 Student 類為例,分別以 age、name 為我們要比較的屬性來構(gòu)造比較器
class Student{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
// 以 Student 類中的 name 屬性構(gòu)造比較器
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2){
return o1.name.compareTo(o2.name);
}
}
// 以 Student 類中的 age 屬性構(gòu)造比較器
class AgeComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2){
return o1.age-o2.age;
}
}
使用比較器來進(jìn)行比較
public class TestDemo{
public static void main(String[] args){
Student s1=new Student("Tom",18);
Student s2=new Student("Alen",25);
// 以 name 的大小來比較
NameComparator nameComparator = new NameComparator();
System.out.println(nameComparator.compare(s1,s2));
// 以 age 的大小來比較
AgeComparator ageComparator = new AgeComparator();
System.out.println(ageComparator.compare(s1,s2));
}
}
// 結(jié)果為:19 和 -7
5. 三種方式對(duì)比
| 覆寫的方法 | 說明 |
|---|---|
| Object.equals | 因?yàn)樗蓄惗际抢^承自 Object 的,所以直接覆寫即可,但是只能比較相等于不相等,不能比較大于或小于 |
| Comparable.compareTo | 需要手動(dòng)實(shí)現(xiàn)接口,侵入性較強(qiáng)。一旦實(shí)現(xiàn),每次用該類都有指定的順序,屬于內(nèi)部順序。但如果要更換比較的方式,則要修改 comparaTo 方法 |
| Comparator.compare | 需要實(shí)現(xiàn)一個(gè)比較器,對(duì)待比較類的侵入性較弱。每次使用,都要確定比較器 |
6. 總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot調(diào)用Poi-tl實(shí)現(xiàn)渲染數(shù)據(jù)并生成Word文檔
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何調(diào)用Poi-tl實(shí)現(xiàn)渲染數(shù)據(jù)并生成Word文檔,文中的示例代碼講解詳細(xì),有需要的小伙伴可以了解下2023-09-09
SpringBoot的內(nèi)嵌和外置tomcat的實(shí)現(xiàn)方式
本文主要介紹了在Spring Boot中定制和修改Servlet容器的配置,包括內(nèi)嵌式和外置式Servlet容器的配置方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-11-11
mybatis-plus配置攔截器實(shí)現(xiàn)sql完整打印的代碼設(shè)計(jì)
在使用mybatis-plus(mybatis)的時(shí)候,往往需要打印完整的sql語(yǔ)句,然而輸出的日志不是很理想,因?yàn)閟ql語(yǔ)句中的關(guān)鍵字段信息都是用?來代替的,所以本文分享了一下自己寫了一個(gè)攔截器實(shí)現(xiàn)了sql完整的打印,需要的朋友可以參考下2024-06-06
Java實(shí)現(xiàn)一個(gè)小說采集程序的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)硪黄狫ava實(shí)現(xiàn)一個(gè)小說采集程序的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的, 現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06
java實(shí)現(xiàn)釘釘機(jī)器人消息推送的示例代碼
這篇文章主要介紹了java實(shí)現(xiàn)釘釘機(jī)器人消息推送的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
Java 實(shí)戰(zhàn)項(xiàng)目之家居購(gòu)物商城系統(tǒng)詳解流程
讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個(gè)家居購(gòu)物商城系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
SpringMVC實(shí)現(xiàn)表單驗(yàn)證功能詳解
這篇文章主要為大家詳細(xì)介紹了SpringMVC 表單驗(yàn)證的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
springboot集成redis啟動(dòng)報(bào)錯(cuò)問題的解決方式
這篇文章主要介紹了springboot集成redis啟動(dòng)報(bào)錯(cuò)問題的解決方式,從錯(cuò)誤信息上看缺少pool2相關(guān)包,查詢資料發(fā)現(xiàn)當(dāng)redis客戶端選擇Lettuce時(shí)候需要增加:commons-pool22023-11-11
添加引用,重啟服務(wù),需要的朋友可以參考下

