簡體   English   中英

兩個hashCodes是否相等是否重要,即使這兩個對象不是來自同一類型?

[英]Does it matter if two hashCodes are equal, even if the two objects aren't from the same type?

假設我有兩個類型AB都有一個唯一的id字段,這里是我通常實現equals()和hashCode()方法的方法:

@Override
public boolean equals(Object obj) {
    return obj instanceof ThisType && obj.hashCode() == hashCode();
}

@Override
public int hashCode() {
    return Arrays.hashCode(new Object[] { id });
}

在這種情況下,假設AB都有一個1-arg構造函數來設置它們各自的id字段,

new A(1).equals(new A(1)) // prints true as expected,
new A(1).equals(new A(2)) // prints false as expected,
new A(1).equals(new B(1)) // prints false as expected.

但是也,

new A(1).hashCode() == new B(1).hashCode() // prints true.

我想知道兩個hashCodes是否相等是否重要,即使這兩個對象不是來自同一類型? hashCode()可以在equals()之外的其他地方使用嗎? 如果是,為了什么目的?


我考慮過實現以下兩種方法:

@Override
public boolean equals(Object obj) {
    return obj != null && obj.hashCode() == hashCode();
}

@Override
public int hashCode() {
    return Arrays.hashCode(new Object[] { getClass(), id });
}

將類添加到hashCode生成將解決此潛在問題 你怎么看? 有必要嗎?

對於不同類的對象,相同的hashCode()無關緊要。 hashCode()只表示對象可能是相同的。 如果例如HashSet遇到相同的hashCode() ,它將使用equals()測試相等性。

規則很簡單:

  • A.equals(B)暗示B.hashcode() == A.hashcode()
  • B.hashcode() != A.hashcode()暗示!A.equals(B)

兩者之間不應該存在其他關系。 如果你在equals()使用hashcode() ,你應該有一個警告。

Hashcode肯定不會用於equals ; 它由基於稱為哈希表的數據結構的集合使用。 從正確性的角度來看,兩個哈希碼彼此相等總是可以的; 這被稱為哈希沖突 ,在一般情況下是不可避免的,唯一的后果是性能較弱。

兩個不同的對象(即使是相同類型)沒有錯誤,但是你的第二個equals()變體看起來很奇怪。 僅當您可以保證僅將對象與相同類型的對象進行比較時,它才會起作用。

Could hashCode() be used somewhere else than in equals()?

支持此方法是為了哈希表的好處,例如java.util.Hashtable.提供的哈希表java.util.Hashtable. 來自javadoc

hashCode的一般契約是:

  • 每當在執行Java應用程序期間多次在同一對象上調用它時,hashCode方法必須始終返回相同的整數,前提是不修改對象上的equals比較中使用的信息。 從應用程序的一次執行到同一應用程序的另一次執行,該整數不需要保持一致。
  • 如果兩個對象根據equals(Object)方法相等,則對兩個對象中的每一個調用hashCode方法必須生成相同的整數結果。 如果兩個對象根據equals(java.lang.Object)方法不相等,則不需要在兩個對象中的每一個上調用hashCode方法必須生成不同的整數結果。 但是,程序員應該知道為不等對象生成不同的整數結果可能會提高哈希表的性能。
  • 如果兩個對象根據equals(java.lang.Object)方法不相等,則不需要在兩個對象中的每一個上調用hashCode方法必須生成不同的整數結果。 但是,程序員應該知道為不等對象生成不同的整數結果可能會提高哈希表的性能

不是這樣,當A擴展B,或B擴展A,那么你的equals方法是錯誤的,因為:

a.equals(b) != b.equals(a)

如果a和b恰好具有相同的哈希碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM