最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中對(duì)象比較的五種方式詳解

 更新時(shí)間:2026年03月25日 09:59:25   作者:yingjuxia.com  
本文詳細(xì)闡述了Java中對(duì)象比較的五種核心方式:==、equals、hashCode、Comparable和Comparator,分析了它們的用途、語義、性能和適用場景,并提供了面試中常問的問題的解答模板,需要的朋友可以參考下

在 Java 中,對(duì)象比較 主要有以下 4–5 種核心方式,它們用途、語義、性能、適用場景完全不同。面試中常被追問的順序通常是:== → equals → hashCode → Comparable → Comparator。

下面按使用頻率和重要性逐一拆解。

1. == (引用比較 / 身份比較)

  • 比較內(nèi)容:兩個(gè)引用變量是否指向堆中同一個(gè)對(duì)象(內(nèi)存地址是否相同)
  • 適用類型
    • 基本類型 → 值比較(int、double、boolean 等)
    • 引用類型 → 地址比較
  • 默認(rèn)行為:Object 類的原始實(shí)現(xiàn)就是 return this == obj;
  • 特點(diǎn):最快,O(1),無方法調(diào)用開銷
  • 典型場景
    • 判斷是否為同一個(gè)實(shí)例(單例模式、緩存命中)
    • null 判斷 if (obj == null)
  • 面試常問陷阱
    • String str1 = “hello”; String str2 = new String(“hello”);
      → str1 == str2 為 false(常量池 vs 堆)

2. equals() (邏輯相等 / 值比較)

  • 默認(rèn)行為(Object 類實(shí)現(xiàn)):return (this == obj); → 等價(jià)于 ==
  • 重寫后語義:大多數(shù)業(yè)務(wù)類重寫后比較內(nèi)容是否相等(而非引用)
  • 經(jīng)典重寫類(JDK 內(nèi)置已重寫):
equals 比較內(nèi)容hashCode 是否同步重寫
String字符序列是否相同
Integer數(shù)值是否相同
BigDecimal數(shù)值 + 精度是否相同
LocalDate年月日是否相同
Arrays內(nèi)容逐個(gè) equals(deepEquals 多維)
  • 重寫 equals 的正確姿勢(契約,必須遵守):
@Override
public boolean equals(Object o) {
    // 1. 引用相同 → 相等
    if (this == o) return true;
    
    // 2. 類型檢查 + null 檢查
    if (o == null || getClass() != o.getClass()) return false;
    
    // 3. 強(qiáng)制轉(zhuǎn)換后逐字段比較(基本類型用 ==,對(duì)象用 equals)
    Person other = (Person) o;
    return age == other.age &&
           Objects.equals(name, other.name) &&
           Objects.equals(idCard, other.idCard);
}
  • Objects.equals(a, b) 工具方法(強(qiáng)烈推薦):
    • 內(nèi)部處理了 null 安全:a == b || (a != null && a.equals(b))

3. hashCode() (散列碼比較,常配合 equals 使用)

作用:為對(duì)象生成一個(gè) int 值,主要用于哈希表(HashMap、HashSet、Hashtable 等)

核心契約(Object 文檔原文):

  1. 同一個(gè)對(duì)象在生命周期內(nèi)多次調(diào)用 hashCode(),返回值必須相同(前提:equals 使用的字段沒變)
  2. 如果 a.equals(b) == true,則 a.hashCode() 必須等于 b.hashCode()
  3. 如果 a.equals(b) == false,不要求 hashCode 不同(但最好不同,以減少哈希沖突)

重寫 equals 必須重寫 hashCode 的原因:

  • 違反第 2 條契約 → HashMap/HashSet 可能出現(xiàn)邏輯錯(cuò)誤(同一個(gè)對(duì)象在集合中出現(xiàn)多次,或 find 不到)

2025–2026 推薦生成方式(IDE 自動(dòng)生成或以下方式):

@Override
public int hashCode() {
    return Objects.hash(name, age, idCard);   // 最簡潔、最推薦(Java 7+)
}
  • 性能提示:hashCode 分布越均勻越好,避免大量對(duì)象 hashCode 相同導(dǎo)致鏈表退化

4. Comparable 接口(自然排序)

  • :java.lang
  • 方法int compareTo(T o)
  • 返回值約定
    • 負(fù)數(shù) → this < o
    • 0 → this == o(邏輯相等,不一定引用相等)
    • 正數(shù) → this > o
  • 典型實(shí)現(xiàn)(String、Integer、LocalDate 等都實(shí)現(xiàn)了):
public class Person implements Comparable<Person> {
    private String name;
    private int age;

    @Override
    public int compareTo(Person o) {
        // 先按年齡升序,年齡相同再按姓名字典序
        int ageCmp = Integer.compare(this.age, o.age);
        if (ageCmp != 0) return ageCmp;
        return this.name.compareTo(o.name);
    }
}
  • 使用場景
    • Collections.sort(list)
    • TreeSet、TreeMap 的默認(rèn)排序
    • Arrays.sort()(對(duì)象數(shù)組)

5. Comparator 接口(定制排序 / 外部比較器)

  • :java.util
  • 方法int compare(T o1, T o2)
  • 特點(diǎn):不侵入原類,可創(chuàng)建多個(gè)比較器
  • Java 8+ 推薦寫法(最常用):
// 方式一:Lambda + comparing
List<Person> list = ...;
list.sort(Comparator.comparingInt(Person::getAge)
                    .thenComparing(Person::getName));

// 方式二:匿名內(nèi)部類(老項(xiàng)目常見)
Comparator<Person> byAgeThenName = (p1, p2) -> {
    int cmp = Integer.compare(p1.getAge(), p2.getAge());
    return cmp != 0 ? cmp : p1.getName().compareTo(p2.getName());
};
  • 使用場景
    • 臨時(shí)排序需求
    • TreeSet/TreeMap 指定比較器
    • Stream.sorted(comparator)

6. 快速對(duì)比總結(jié)表(面試最愛畫的表)

比較方式比較內(nèi)容是否可重寫是否侵入類典型集合支持性能面試出現(xiàn)頻率
==引用地址極高★★★★★
equals()邏輯相等(內(nèi)容)HashMap/HashSet★★★★★
hashCode()散列值是(必須與equals一致)HashMap/HashSet極高★★★★☆
compareTo()自然排序大小TreeSet/TreeMap 默認(rèn)★★★★
Comparator定制排序任意集合/Stream★★★★

7. 常見面試連環(huán)追問(建議準(zhǔn)備的回答模板)

重寫了 equals 沒重寫 hashCode 會(huì)有什么問題?
→ HashMap 中 put 后 get 找不到;Set 中出現(xiàn)重復(fù)元素

String 為什么可以直接用 == 比較常量池字符串?
→ 字符串常量池 + intern() 機(jī)制

如何比較兩個(gè)對(duì)象是否“完全相等”(包括所有字段深比較)?
→ Apache Commons Lang → ReflectionToStringBuilder 或 Objects.deepEquals(多維數(shù)組)

Java 14+ Record 類自動(dòng)實(shí)現(xiàn)了哪些比較相關(guān)方法?
→ equals、hashCode、toString 全部按所有組件字段自動(dòng)生成

排序時(shí)如果 compareTo 返回 0,但 equals 返回 false 會(huì)怎樣?
→ TreeSet/TreeMap 會(huì)認(rèn)為相等而覆蓋(違反 SortedSet 語義)

希望這份總結(jié)能幫你快速建立 Java 對(duì)象比較的完整知識(shí)圖譜。

如果你正在準(zhǔn)備面試,想針對(duì)某一種方式(比如 equals + hashCode 的完整手寫實(shí)現(xiàn)、或 Comparator 的多種寫法)要更詳細(xì)的代碼示例,或者想看某個(gè)具體場景的對(duì)比代碼,直接告訴我,我可以繼續(xù)展開。

以上就是Java中對(duì)象比較的五種方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Java對(duì)象比較方式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java使用RedisTemplate模糊刪除key操作

    Java使用RedisTemplate模糊刪除key操作

    這篇文章主要介紹了Java使用RedisTemplate模糊刪除key操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 如何解決struts2日期類型轉(zhuǎn)換

    如何解決struts2日期類型轉(zhuǎn)換

    在Struts2中,一般的內(nèi)置類型都會(huì)在由系統(tǒng)自動(dòng)進(jìn)行轉(zhuǎn)換.但是Date類型好像有時(shí)候行,有時(shí)候不行。比如我這次,本地運(yùn)行正常,一上測試服務(wù)器就不行了。這個(gè)轉(zhuǎn)換類是從網(wǎng)上看的:
    2013-03-03
  • Spring Boot 異步HTTP客戶端配置使用

    Spring Boot 異步HTTP客戶端配置使用

    本文詳細(xì)介紹SpringBoot中使用WebClient實(shí)現(xiàn)異步HTTP請(qǐng)求的完整方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-12-12
  • java list隨機(jī)抽取元素的案例

    java list隨機(jī)抽取元素的案例

    這篇文章主要介紹了java list隨機(jī)抽取元素的案例,具有很好的參考,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 如何在spring boot中進(jìn)行參數(shù)校驗(yàn)示例詳解

    如何在spring boot中進(jìn)行參數(shù)校驗(yàn)示例詳解

    這篇文章主要介紹了如何在spring-boot中進(jìn)行參數(shù)校驗(yàn)及l(fā)ombok的使用詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 一文詳解java如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

    一文詳解java如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

    從?Java?8?開始,便引入了一種稱為“流式?API”的編程風(fēng)格,當(dāng)然也被稱為“鏈?zhǔn)皆O(shè)置”或“鏈?zhǔn)秸{(diào)用”,本文主要來和大家討論一下如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,感興趣的可以了解下
    2023-12-12
  • java編寫簡易貪吃蛇游戲

    java編寫簡易貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了java編寫簡易貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Java編程實(shí)現(xiàn)逆波蘭表達(dá)式代碼示例

    Java編程實(shí)現(xiàn)逆波蘭表達(dá)式代碼示例

    本文主要對(duì)Java算法逆波蘭表達(dá)式的相關(guān)內(nèi)容作了介紹,涉及逆波蘭表達(dá)式的定義已經(jīng)在Java中的實(shí)現(xiàn),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • Spring Boot如何通過CORS處理跨域問題

    Spring Boot如何通過CORS處理跨域問題

    這篇文章主要介紹了Spring Boot如何通過CORS處理跨域問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java JDBC批量執(zhí)行executeBatch方法詳解

    Java JDBC批量執(zhí)行executeBatch方法詳解

    這篇文章主要介紹了Java JDBC批量執(zhí)行executeBatch方法詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

宁乡县| 体育| 天气| 大同县| 太湖县| 馆陶县| 温宿县| 临沂市| 二连浩特市| 保德县| 武山县| 夏邑县| 夹江县| 泾川县| 绩溪县| 临潭县| 梨树县| 道孚县| 武鸣县| 揭阳市| 加查县| 自治县| 垫江县| 错那县| 华亭县| 芦山县| 肥西县| 介休市| 南投县| 民乐县| 东源县| 寿阳县| 金塔县| 富裕县| 张家口市| 丰县| 延庆县| 天柱县| 闸北区| 苏州市| 汉寿县|