// 錯誤示範
@Override
public boolean equals(Object obj) {
return this.hashCode() == obj.hashCode(); // 嚴重錯誤!
}
哈希碰撞必然存在:hashCode() 返回 int(40 億空間),而對象狀態組合空間遠大於此。根據鴿巢原理,不同對象極大概率產生相同 hashCode。若直接比較 hashCode,會導致 不同對象被誤判為相等,破壞 Set、Map 去重語義,引發極難排查的業務 Bug。
@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);
}
equals 比較的字段。31 * result + field.hashCode())。| 誤區 | 後果 |
|---|---|
| 只比較 hashCode | 不同對象誤判相等,Set/Map 失效 |
| equals 用 instanceof 而非 getClass | 破壞對稱性,子類比較出錯 |
| hashCode 僅用單一字段 | 碰撞率極高,HashMap 退化為鏈表,性能崩潰 |
| 可變對象作 Map Key | 修改字段後無法取出 Value |
equals/hashCode(Alt+Insert → equals and hashCode)。@EqualsAndHashCode 註解自動實作。EqualsVerifier.forClass(MyClass.class).verify();嚴守契約、理解碰撞本質,是寫出健壯 Java 領域模型的基石。