一、 Set集合的本質:Map的外包裝(Wrapper)
二、 equals與hashCode的生死契約(The Contract)
Java 官方在 Object 類別中明確定義了兩者的約束規則:
* 一致性(Consistency):在物件未被修改的前提下,多次呼叫hashCode()必須返回相同的整數。
* 等價必然同雜湊(equals=>hashCode):如果兩個物件透過 equals()比較為 true,則兩者的hashCode()數值必須完全相同。
* 同雜湊不必然等價(hashCode => equals不成立):兩個物件的 hashCode()相同(發生雜湊碰撞),它們透過equals()比較不一定為true。
三、 只改寫 equals 卻未改寫 hashCode 的災難
四、 核心架構地雷:修改 Set 中的元素引發記憶體洩漏(Memory Leak)
這是 Java 最經典、最難排查的隱蔽 Bug 之一。
地雷重現場景:
public class Point {
private int x;
private int y;
public Point(int x, int y) { this.x = x; this.y = y; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Point p)) return false;
return x == p.x && y == p.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y); // 雜湊值與 x, y 綁定
}
public void setX(int x) { this.x = x; } // 提供 Setter 允許修改內部狀態
}
崩潰後果剖析:
set.contains(p) 返回 false:
set.remove(p) 失敗:
刪除時同樣去 Bucket B 尋找,結果刪除失敗,返回 false。
幽靈物件與記憶體洩漏(Memory Leak):
五、 工程防禦三大鐵律