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

我們知道對(duì)于引用類型,用 == 號(hào)比較的其實(shí)是引用變量的地址,所以即使兩個(gè)對(duì)象的值相等,但是由于地址不同所以結(jié)果也可能是錯(cuò)的,并且還由于自定義類中的屬性不為1,所以不重寫(xiě)基類的 equals 方法的話,是無(wú)法正確比較對(duì)象的。
2.2 覆寫(xiě) equals 方法的規(guī)則
- 如果指向同一個(gè)對(duì)象,則返回 true
- 如果傳入的值為 null,則返回 false
- 如果傳入的對(duì)象類型不是自定義類或其子類,則返回 false
- 最后比較對(duì)象的各個(gè)屬性,如果是基本類型,則可以直接用 == 比較;如果是引用類型,則使用 equals 方法比較
2.3 實(shí)現(xiàn)代碼
以下用自定義的 Student 類為例,重寫(xiě)其基類的 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 局限性
覆寫(xiě)基類 equals 的方法雖然可以使自定義的類被比較,但是該方法只能進(jìn)行相等和不相等的比較,不能按照大于或小于的方式進(jìn)行比較。
3. 方法二:基于 Comparable 接口的比較
3.1 介紹
該方法在 解析 Java 的多態(tài)、抽象類和接口 這章介紹過(guò)了,有興趣了解的 uu 可以去那篇文章里面看看
注意:
Comparable 是 java.lang 中的接口類,可以直接使用。
3.2 使用方法
- 先讓自定義的類繼承 Comparable 接口
- 再根據(jù)我們要以自定義類的哪個(gè)屬性去比較,來(lái)重寫(xiě) 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è)屬性來(lái)比較大小,但是當(dāng)我們確定好了以哪一個(gè)屬性來(lái)比較對(duì)象的話,那么當(dāng)我們想要使用另一個(gè)屬性比較對(duì)象時(shí),則需要修改重寫(xiě) compareTo 方法
4. 方法三:基于 Comparator 接口,自定義比較器的比較
4.1 介紹
該方法在 解析 Java 的多態(tài)、抽象類和接口 這章介紹過(guò)了,有興趣了解的 uu 可以去那篇文章里面看看
注意:
Comparator 是 java.util 包中的泛型接口類,使用時(shí)必須導(dǎo)入對(duì)應(yīng)的包。
4.2 使用方法
- 我們選擇一個(gè)自定義類中要比較的屬性,可以再定義一個(gè)類(即比較器),繼承于 Comparator 接口
- 在該接口中,重寫(xiě) Comparator 接口的 compare 方法,該方法重寫(xiě)的就是對(duì)這個(gè)屬性比較的規(guī)則
- 使用時(shí)我們就使用 compare 方法,
4.3 實(shí)現(xiàn)代碼
以下用自定義的 Student 類為例,分別以 age、name 為我們要比較的屬性來(lái)構(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;
}
}
使用比較器來(lái)進(jìn)行比較
public class TestDemo{
public static void main(String[] args){
Student s1=new Student("Tom",18);
Student s2=new Student("Alen",25);
// 以 name 的大小來(lái)比較
NameComparator nameComparator = new NameComparator();
System.out.println(nameComparator.compare(s1,s2));
// 以 age 的大小來(lái)比較
AgeComparator ageComparator = new AgeComparator();
System.out.println(ageComparator.compare(s1,s2));
}
}
// 結(jié)果為:19 和 -7
5. 三種方式對(duì)比
| 覆寫(xiě)的方法 | 說(shuō)明 |
|---|---|
| Object.equals | 因?yàn)樗蓄惗际抢^承自 Object 的,所以直接覆寫(xiě)即可,但是只能比較相等于不相等,不能比較大于或小于 |
| 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)文章
關(guān)于@RequestBody,@PathVariable,無(wú)注解使用及說(shuō)明
本文詳細(xì)介紹了@RequestBody、@PathVariable和無(wú)注解三種參數(shù)注解的使用場(chǎng)景、核心特征及對(duì)比,總結(jié):根據(jù)數(shù)據(jù)類型和場(chǎng)景選擇合適注解,可提升接口規(guī)范性和性能2025-10-10
Spring實(shí)現(xiàn)Aware接口自定義獲取bean的兩種方式
這篇文章主要介紹了Java編程實(shí)現(xiàn)Aware接口自定義獲取bean的兩種方式,通過(guò)BeanFactoryAware和ApplicationContextAware,具有一定參考價(jià)值,需要的朋友可以了解下。2017-09-09

