[英]how to override this hashCode method?
至於人的定義:
public class Person {
private int id;
private int characteristics;
public boolean equals (Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Person) {
if (id == ((Person) obj).id) {
return true;
} else if (characteristics == ((Person) obj).characteristics) {
return true;
}
}
return false;
}
}
原因2如果a.equals(b)
返回true
,那么Person
對象a
和b
必須具有相同的哈希碼,我應如何實現hashCode
方法?
解
根據Java的等效協議,我的equals
方法實現不正確:不滿足傳遞性 : a.id = 1
, a.characteristic = 2
, b.id = 1
, b.characteristic = 3
, c.id = 2
, c.characteristic = 3
; a.equals(b) == true
, b.equals(c) == true
,但是a.equals(c) == false
。
由於您的類在它們各自的id
或characteristics
字段相等時認為對象相等,因此您在此處可以合理使用的唯一哈希碼是所有實例的常量值:
public int hashCode() {
return 0;
}
這將使基於散列的查找表現出可怕的效果。
在equals()
進行或非測試通常是一個壞主意; 這些對象實際上並不相等 ,對嗎? 也許它們只是“彼此匹配”? 也許您應該考慮單獨保留equals()
並實現其他比較方法。
正如Thomasz指出的那樣,您的equals()
測試不是傳遞性的; 如果a.equals(b) && b.equals(c)
為true,則a.equals(c)
必須為true。 對於您的重載情況並非如此,因此您的實現違反了equals()
的約定 。 我強烈建議您以其他方法實施此測試,而不要將equals()
放在首位。
這是您的班級自動生成的intellij-idea :
@Override
public int hashCode() {
int result = id;
result = 31 * result + characteristics;
return result;
}
經過幾次重構:
@Override
public int hashCode() {
return 31 * id + characteristics;
}
記錄下來,僅僅是我還是您的equals()
被破壞了? 如果id
或characteristics
相等,則認為兩個對象相等,但不一定要兩個都相等。 這意味着您的平等性不是可傳遞的 ,一旦您的物體進入曠野,它可能會帶來真正意想不到的副作用。
這是一個不錯的實現:
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Person)) {
return false;
}
Person person = (Person) o;
return characteristics == person.characteristics && id == person.id;
}
如果具有相同的id
意味着始終具有相同的characteristics
(對於equals()
有效,這似乎是必需的),那么您的哈希碼可以單獨使用characteristics
:
@Override
public int hashCode() {
return characteristics;
}
如果不是這種情況,您可能要重新考慮使用Java相等性來表達這種關系,如@cdhowie所建議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.