所有 Java 對象繼承 Object 的兩個方法:
equals(Object obj):判斷邏輯相等性。hashCode():返回哈希碼,供 HashMap、HashSet 等基於哈希的容器高效存取。鐵律: 若覆寫 equals(),必須覆寫 hashCode()。契約要求:a.equals(b) == true ⇒ a.hashCode() == b.hashCode()。反向不要求(允許哈希碰撞)。
equals(): 引用相等 (this == obj)。hashCode(): 從內存地址衍生(可能碰撞)。Integer.equals() 比較 intValue();String.equals() 比較字符序列。這使它們可作為可靠的 Map Key。若 Integer 不覆寫,作為 HashMap Key 時,get() 必須使用與 put() 完全相同的對象實例才能命中,極不實用且易錯。覆寫後,語義相等的不同實例均可正確存取。
x.equals(x) == true (x ≠ null)x.equals(y) ⇔ y.equals(x)x.equals(y) && y.equals(z) ⇒ x.equals(z)x.equals(null) == false可變對象作 Key 會導致修改字段後哈希碼變化,在 Map 中「找不到自己」。String、包裝類、BigInteger、LocalDate 等不可變類是完美 Key。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyClass that = (MyClass) o;
return Objects.equals(field1, that.field1) &&
Objects.equals(field2, that.field2) &&
Double.compare(that.field3, field3) == 0; // 浮點數比較
}
@Override
public int hashCode() {
return Objects.hash(field1, field2, field3);
}
Objects.equals() 安全處理 null。Objects.hash() 自動組合哈希碼(Java 7+)。Double.compare / Float.compare 避免 NaN、-0.0 陷阱。equals() 比較的字段,保持一致性。MyClass 而非 Object → 重載而非覆寫,破壞多態。null 或 getClass() → 拋出 NPE 或違反對稱性。hashCode()(如只用一個字段) → 嚴重哈希碰撞,退化為鏈表 O(n)。正確實現 equals()/hashCode() 是 Java 開發基本功。遵循契約、使用 Objects 輔助類、堅持不可變性、覆蓋所有相關字段,能讓你的類在集合框架中表現可靠、高效。