簡體   English   中英

除了 Collections API,在 Java 中重寫 hashCode 有什么用?

[英]What is the use of overriding hashCode in Java other than Collections API?

面試官問這個問題,大多數與哈希碼相關的答案都用於分桶,它檢查等於搜索對象。

是否有任何其他通用用例或場景,其中哈希碼是有益的並且可以在例行程序中使用?

最近我使用了 JPA,它拋出異常"Composite-id class does not override hashCode()"但它再次被 hibernate 的實現類使用。 狡猾,我們可以在哪些其他地方或場景中使用哈希碼而不是集合,尤其是您自己使用過的場景。

class a {
    public int hashCode() {
    }
}

class b {
    public static void main(String[] str) {
        //In what ways can i use hashcode here?
    }
}

面試問題中的一個小語義錯誤。 哈希碼不用於檢查相等性,而是用於檢測不相等性。 如果哈希碼不同,則保證對象是不相等的。 如果代碼相等,則對象可能相等,需要使用 equals 方法進行檢查。

也就是說,如果哈希碼被緩存,它可以用來加速 equals 方法。

  • 假設您只覆蓋 equals 而不是 hashCode
  • 這意味着 hashCode 是從 Object 繼承的
  • Object.hashCode 總是嘗試為不同的對象返回不同的哈希碼(無論它們是否相等)
  • 這意味着您最終可能會為您認為相等的兩個對象使用不同的哈希碼。
  • 這反過來導致這兩個相等的對象最終出現在基於散列的集合(如 HashSet)中的不同桶中。
  • 這會導致此類集合中斷。

更多參考: https : //programming.guide/java/overriding-hashcode-and-equals.html

假設您的類永遠不會在任何集合中使用(盡管這種可能性很小),它將在多個地方被其他開發人員使用。 任何使用您的類的開發人員都會期望,如果該類的兩個實例基於 equals 方法相等,則它們應該產生相同的 hashCode 值。 如果 hashCode 沒有被覆蓋以與 equals 一致,那么這個基本假設將被打破,這將阻止他們的代碼正常運行。

來自 Effective Java,第 3 版:

第 11 條:當您覆蓋相等時始終覆蓋哈希碼

您必須在每個覆蓋 equals 的類中覆蓋 hashCode。 如果你不這樣做,你的類將違反 hashCode 的一般契約,這將阻止它在 HashMap 和 HashSet 等集合中正常運行。 這是根據對象規范改編的合同:

• 當在應用程序執行期間對一個對象重復調用 hashCode 方法時,它必須始終返回相同的值,前提是在 equals 比較中使用的信息沒有被修改。 該值不需要從應用程序的一次執行到另一次執行保持一致。

• 如果根據equals(Object) 方法,兩個對象相等,則對這兩個對象調用hashCode 必須產生相同的整數結果。

• 如果根據equals(Object) 方法,兩個對象不相等,則不需要對每個對象調用hashCode 必須產生不同的結果。 但是,程序員應該意識到為不相等的對象生成不同的結果可能會提高哈希表的性能。

當您無法覆蓋 hashCode 時違反的關鍵規定是第二條:相等的對象必須具有相等的哈希碼。 根據類的 equals 方法,兩個不同的實例在邏輯上可能是相等的,但對於 Object 的 hashCode 方法,它們只是兩個沒有太多共同點的對象。 因此,Object 的 hashCode 方法返回的是兩個看似隨機的數字,而不是合約要求的兩個相等的數字。

暫無
暫無

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

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