equals和hashcode方法重寫

在 Java 中,當你需要基于對象的內容而非引用地址來判斷兩個對象是否相等時,就需要重寫equalshashCode方法。以下是具體場景和實現原則:

一、為什么需要同時重寫這兩個方法?

  1. equals方法:默認比較對象的內存地址(==),若需比較內容(如兩個Person對象的nameage是否相同),則需重寫。
  2. hashCode方法
    • HashMap/HashSet 依賴:這些集合通過hashCode快速定位元素,若不重寫,即使內容相同的對象也會被存儲多次(因為默認hashCode基于內存地址計算)。
    • 約定:Java 規范要求若兩個對象equalstrue,則hashCode必須相同
hashCode方法的重寫原則
  • 相同對象必須返回相同哈希值(根據equals的結果)。
  • 哈希值分布均勻:減少哈希沖突。

?

常見誤區

  1. 只重寫equals不重寫hashCode
    • 導致 HashMap/HashSet 無法正常工作(如無法正確去重)。
  2. 使用錯誤的哈希計算方式
    • 例如返回固定值(如return 1;),會導致所有對象哈希沖突,性能嚴重下降。
  3. 忽略父類屬性
    • 若父類有重要字段,需在equalshashCode中包含父類的判斷邏輯(通過super.equals()super.hashCode())。

?

哈希集合的工作原理

HashMap 的 put () 流程
  1. 計算哈希值:通過key.hashCode()確定存儲桶的位置。
  2. 處理哈希沖突:若多個鍵的hashCode相同,在桶內通過equals()比較鍵是否相等。
    • equals()true,則覆蓋原值;
    • equals()false,則以鏈表 / 紅黑樹形式存儲。

在 Java 中,正確重寫equalshashCode方法需要遵循特定的規則和步驟。以下是詳細的實現指南和示例:

一、重寫equals方法的步驟

1. 檢查對象引用是否相同

java

運行

if (this == o) return true;
2. 檢查對象是否為null或類型不匹配

java

運行

if (o == null || getClass() != o.getClass()) return false;
3. 強制類型轉換并比較關鍵字段

使用Objects.equals比較引用類型(處理null安全),直接比較基本類型:

java

運行

Person person = (Person) o;
return age == person.age &&           // 基本類型用==Objects.equals(name, person.name); // 引用類型用Objects.equals

二、重寫hashCode方法的步驟

1. 使用關鍵字段生成哈希值

推薦使用Objects.hash()方法,它會自動處理null并組合多個字段:

java

運行

@Override
public int hashCode() {return Objects.hash(name, age);
}

三、完整示例

以下是一個Person類的完整實現:

java

運行

import java.util.Objects;public class Person {private String name;private int age;private String email; // 可選字段,可能為null// 構造方法、getter/setter略@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age &&Objects.equals(name, person.name) &&Objects.equals(email, person.email);}@Overridepublic int hashCode() {return Objects.hash(name, age, email);}
}

四、進階技巧

1. 處理繼承關系

若父類也有重要字段,需調用父類的equalshashCode

java

運行

@Override
public boolean equals(Object o) {if (!super.equals(o)) return false; // 先檢查父類字段// 再比較子類字段...
}@Override
public int hashCode() {return Objects.hash(super.hashCode(), childField);
}
2. 處理數組字段

使用Arrays.equalsArrays.hashCode

java

運行

private int[] scores;@Override
public boolean equals(Object o) {// ...return Arrays.equals(scores, person.scores);
}@Override
public int hashCode() {return Objects.hash(name, Arrays.hashCode(scores));
}
3. 性能優化

若計算哈希值開銷大,可緩存結果(適用于不可變對象):

java

運行

private int hashCode; // 緩存哈希值@Override
public int hashCode() {int result = hashCode;if (result == 0) {result = Objects.hash(name, age);hashCode = result;}return result;
}

五、常見錯誤

錯誤示例問題
僅比較部分字段如忽略email字段,可能導致equals邏輯不一致。
使用==比較引用類型name == person.name,未處理null或不同實例但內容相同的情況(如new String("abc"))。
返回固定哈希值return 1;,導致所有對象哈希沖突,哈希集合性能嚴重下降。
違反對稱性a.equals(b)true,但b.equals(a)false(例如比較時忽略了子類字段)。

六、IDE 自動生成(以 IntelliJ IDEA 為例)

  1. 右鍵點擊類內空白處 →?Generate?→?equals() and hashCode()
  2. 選擇需要參與比較的字段
  3. 確認生成的代碼(IDE 通常會生成正確實現)

七、驗證重寫是否正確

編寫單元測試驗證行為:

java

運行

import static org.junit.Assert.*;public class PersonTest {@Testpublic void testEqualsAndHashCode() {Person p1 = new Person("Alice", 20, "alice@example.com");Person p2 = new Person("Alice", 20, "alice@example.com");assertTrue(p1.equals(p2)); // 內容相同,應返回trueassertEquals(p1.hashCode(), p2.hashCode()); // 哈希值必須相同Person p3 = new Person("Bob", 30, null);assertFalse(p1.equals(p3)); // 內容不同,應返回false}
}

總結

關鍵點實現方法
equals1. 引用相等檢查
2. 類型和null檢查
3. 字段比較(使用Objects.equals
hashCode使用Objects.hash()組合所有參與equals比較的字段
繼承關系調用父類的equalshashCode
數組字段使用Arrays.equalsArrays.hashCode

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/91772.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/91772.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/91772.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Excel批量生成SQL語句 Excel批量生成SQL腳本 Excel拼接sql

Excel批量生成SQL語句 Excel批量生成SQL腳本 Excel拼接sql一、情境描述在Excel中有標準的格式化數據,如何快速導入到數據庫中呢?有些工具支持Excel導入的,則可以快速導入數據---例如Navicat;如果不支持呢,如果將Excel表…

金和OA C6 DelTemp.aspx 存在XML實體注入漏洞(CVE-2025-7523)

免責聲明 本文檔所述漏洞詳情及復現方法僅限用于合法授權的安全研究和學術教育用途。任何個人或組織不得利用本文內容從事未經許可的滲透測試、網絡攻擊或其他違法行為。 前言:我們建立了一個更多,更全的知識庫。每日追蹤最新的安全漏洞,追中25HW情報。 更多詳情: http…

Android性能優化之啟動優化

一、啟動性能瓶頸深度分析 1. 冷啟動階段耗時分布階段耗時占比關鍵阻塞點進程創建15%fork進程 加載ZygoteApplication初始化40%ContentProvider/庫初始化Activity創建30%布局inflate 視圖渲染首幀繪制15%VSync信號等待 GPU渲染2. 高頻性能問題 初始化風暴:多個庫…

中國優秀開源軟件及企業調研報告

中國優秀開源軟件及企業調研報告 引言 當前中國開源生態呈現蓬勃發展態勢,技術創新領域尤為活躍,其中人工智能大模型成為開源動作的核心聚焦方向。2025年上半年,國內AI領域開源生態迎來密集爆發,頭部科技企業相繼推出重要開源舉…

C++語法 匿名對象 與 命名對象 的詳細區分

目錄一、匿名對象的本質定義二、匿名對象的調用邏輯:即生即用的設計三、與命名對象的核心差異四、匿名對象的典型應用場景五、匿名對象的潛在風險與規避六、總結:匿名對象的價值定位在 C 類與對象的知識體系中,匿名對象是一種容易被咱們忽略&…

【Fedora 42】Linux內核升級后,鼠標滾輪失靈,libinput的鍋?

解決: 最近在玩Fedora 42,升級了一次給俺鼠標滾輪干失靈了。原因可能是 libinput 升級后與Fedora升級后的某些配置有沖突?(搞不懂) sudo dnf downgrade libinput降級 libinput (1.28.901-1.fc42 -> 1.28.0-1.fc42) …

虛擬機centos服務器安裝

創建虛擬機選擇鏡像啟動 移除舊的repo文件: sudo rm -f /etc/yum.repos.d/CentOS-Base.repo下載阿里云的repo文件: 對于CentOS 7: sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo清除緩存并生…

【js(1)一文解決】var let const

var let const!在 ES6 之前,JavaScript 只有兩種作用域: 全局變量 與 函數內的局部變量一、var1. 函數級作用域,有變量提升二、let(ES6新增)1. 塊級作用域,不會影響外部作用域2.let 關鍵字在不同…

論螺旋矩陣

螺旋矩陣題型總結。我刷了幾道螺旋矩陣相關的題目,這里我們介紹一下一些常見的解法。 螺旋矩陣 方形矩陣 當我們遇到n*n的方形矩陣時,可以用一種特殊的解法來遍歷實現,以下面這道題為例: 59. 螺旋矩陣 II 我們可以定義幾個變…

數學金融與金融工程:學科差異與選擇指南

在金融領域的學習中,數學金融與金融工程常被混淆。兩者雖同屬 “金融 量化” 交叉方向,但在研究側重、培養路徑上有顯著區別。結合學科特點與行業實踐,幫大家理清兩者的核心差異,以便更精準地選擇方向。一、核心差異:…

包管理工具npm cnpm yarn的使用

包管理工具 1. 什么是包管理工具? 包管理工具是用于管理和安裝 Node.js 項目依賴的工具。它們提供了一種結構化的方式來管理項目的依賴關系,使得項目的依賴管理變得更加便捷和可靠。 2. 常見的包管理工具有哪些? npm(Node Package Manager):是 Node.js 的默認包管理工…

網絡基礎13--鏈路聚合技術

一、鏈路聚合概述定義將多條物理鏈路捆綁為一條邏輯鏈路,提升帶寬與可靠性。2. 應用場景交換機/路由器/服務器之間的互聯,支持二層(數據鏈路層)和三層(網絡層)聚合。二、核心作用增加帶寬聚合鏈路的總帶寬 …

一文講清楚React性能優化

文章目錄一文講清楚React性能優化1. React性能優化概述2. React性能優化2.1 render優化2.2 較少使用內聯函數2.3 使用React Fragments避免額外標記2.4 使用Immutable上代碼2.5 組件懶加載2.6 服務端渲染2.7 其他優化手段一文講清楚React性能優化 1. React性能優化概述 React通…

3.0 - 指針-序列化

一、關于Serialize的使用 可以使用該指令臨時將用戶程序的多個結構化數據項保存到緩沖區中(最好位于全局數據塊中)。用于保存轉換后數據的存儲區的數據類型必需為 ARRAY of BYTE 或 ARRAY of CHAR 相當于把一個struct或其他自定義類型變成一個字節數組。 比如我有好幾個結構體…

【論文精讀】基于共識的分布式量子分解算法用于考慮最優傳輸線切換的安全約束機組組合

本次分析的論文《Consensus‐Based Distributed Quantum Decomposition Algorithm for Security‐Constrained Unit Commitment Considering Optimal Transmission Switching》于2025年6月25日在《Advanced Quantum Technologies》期刊上公開發表。本文提出了一個新的基于共識的…

MyBatis-Flex代碼生成

引入依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok<…

知網論文批量下載pdf格式論文,油猴腳本

任務描述 今天收到一個任務&#xff0c;在知網上&#xff0c;把一位專家所有的論文全都下載下來&#xff0c;要保存為PDF格式。 知網不支持批量導出PDF格式論文。一個一個下載PDF&#xff0c;太繁瑣了。 解決方案&#xff1a;找到一個油猴腳本&#xff0c;這個腳本可以從知網…

低代碼平臺:驅動項目管理敏捷開發新范式

隨著企業數字化轉型加速&#xff0c;項目管理系統已從單一任務跟蹤工具到集成流程自動化、資源調度、跨團隊協作與風險監控的綜合平臺&#xff0c;項目管理系統的功能復雜度持續提升。然而&#xff0c;根據Gartner 2024年研究報告顯示&#xff0c;約60%的項目管理系統因未能有效…

圖機器學習(11)——鏈接預測

圖機器學習&#xff08;11&#xff09;——鏈接預測0. 鏈接預測1. 基于相似性的方法1.1 基于指標的方法1.2 基于社區的方法2. 基于嵌入的方法0. 鏈接預測 鏈接預測 (link prediction)&#xff0c;也稱為圖補全&#xff0c;是處理圖時常見的問題。具體而言&#xff0c;給定一個…

簡單2步配置CadenceSkill開發編輯器,支持關鍵字高亮

Cadence 使用過程中難免會與skill打交道&#xff0c;有時候網上找到的開源skill&#xff0c;想要查看或者編輯一下&#xff0c;常規的txt編輯器沒有關鍵字高亮&#xff0c;看起來極為不方便。 利用Sublime Text可以很快速配置出支持skill關鍵字高亮的編輯器。 一、安裝 Sublime…