首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 集合框架深度解析:HashSet 存儲原理與 hashCode/equals 契約

     編輯:Java 綜合教學

Java 集合框架深度解析:HashSet 存儲原理與 hashCode/equals 契約

Set 特徵:無序、不可重複。HashSet 底層基於哈希表(HashMap)實現,元素按 hashCode() 分桶,equals() 判斷相等。

默認行為演示

class Demo { }
Demo d1 = new Demo(), d2 = new Demo();
System.out.println(d1); // Demo@1a8fa0f0
System.out.println(d2); // Demo@4b8efa2f
HashSet<Demo> set = new HashSet<>();
set.add(d1); set.add(d2);
System.out.println(set); // [Demo@4b8efa2f, Demo@1a8fa0f0] 順序不可預期

未重寫 hashCode/equals 時,默認按對象地址計算哈希碼,兩對象視為不同,均可入集合。

重寫 hashCode() 返回固定值

class Demo {
    @Override public int hashCode() { return 90; } // 固定哈希碼
    @Override public boolean equals(Object obj) {
        System.out.println("調用 equals 判斷相等");
        return super.equals(obj); // 默認比較地址
    }
}
// 輸出:
// Demo@5a
// Demo@5a
// 調用 equals 判斷相等
// [Demo@5a, Demo@5a]

哈希碼相同 → 進入同一桶 → 呼叫 equals() 比較 → 地址不同 → 判定為不同元素 → 以鏈表/紅黑樹形式順延存儲。

核心契約

  1. 若 a.equals(b) == true,則 a.hashCode() == b.hashCode() 必須成立;
  2. hashCode() 相等不代表 equals() 相等(哈希碰撞);
  3. 作為 Set 元素或 Map 鍵的類,必須同時重寫 兩方法,保持一致性。

理解此機制,可避免「明明相等卻存入兩份」或「本應不同卻被視為重複」的低級錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved