若兩物件
equals()回傳 true,則其hashCode()必須相等。
反向不要求:hashCode 相等不代表 equals 為真 (哈希碰撞)。
Object.hashCode():通常為記憶體地址映射 (Native 實作)Object.equals():比較記憶體地址 (即 ==)HashMap/HashSet 內部維護哈希桶陣列:
hashCode() → 定位桶索引equals() 逐一比對違反契約後果:
equals()=true 但 hashCode() 不等 → 物件落入不同桶 → 查找/刪除失效、記憶體洩漏、重複元素public class User {
private Long id;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return Objects.equals(id, user.id) && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name); // JDK 7+ 推薦
// 手寫: 31 * (id != null ? id.hashCode() : 0) + (name != null ? name.hashCode() : 0)
}
}
Objects.equals/hash (空值安全)String)| 誤區 | 後果 |
|---|---|
| 只重寫 equals | Hash 集合失效 |
| hashCode 用隨機數/時間 | 同一物件多次調用不等,集合找不到自己 |
| equals 比較 hashCode | 邏輯循環、效能差 |
| 業務 Key 用可變物件 | 修改欄位後導致 Map 找不到原 Key |