Java Collections – hashCode() 和 equals() – 如何在 Java 中覆蓋 equals() 和 hashcode() 方法?

已發表: 2018-08-08
Java 集合 hashCode 和 equals

Java 中的equals()hashCode()是在 Object 類和部分或核心 Java 庫中聲明的兩個基本方法。

如果您在 Java 中有以下任何問題,那麼您來對地方了。

  • Java 實踐 -> 實現 equals
  • override – 在 Java 中覆蓋 equals 和 hashCode
  • 如何在java中覆蓋equals()方法
  • 如何在java中覆蓋hashCode()方法
  • 如何在 Java 中覆蓋 equals 和 hashCode 方法
  • 如何以及為什麼在 Java 中重寫 equals 方法
  • 如果覆蓋 equals(),為什麼總是覆蓋 hashcode()?

讓我們看一個簡單的例子來了解第一個Reference EqualityLogical Equality 。 相等運算符 (==) 將兩個字符串的引用(內存中的地址)作為兩個不同的數字進行比較——這稱為Reference equality

Logical equality比較對象的數據而不是引用的值。

輸出:

hashCodeequals密切相關:

  • 如果您覆蓋equals ,則必須覆蓋hashCode
  • hashCode必須為相等的對像生成相等的值。
  • equalshashCode必須依賴於same set of significant fields 。 您必須在這兩種方法中使用相同的字段集。 您不需要使用所有字段。 例如,一個依賴於其他的計算字段很可能應該從equalshashCode中省略。

實現equals時,根據類型對字段進行不同的比較:

  • 對象字段,包括集合:使用equals
  • 類型安全枚舉:使用equals== (在這種情況下,它們等同於相同的東西)
  • 可能為空的對象字段:同時使用==equals
  • 數組字段:使用Arrays.equals
  • floatdouble以外的原始字段:使用==
  • float : 轉換為int使用Float.floatToIntBits ,然後使用==
  • double :使用Double.doubleToLongBits轉換為long ,然後使用==

實現hashCode

  • 如果一個類覆蓋了equals ,它必須覆蓋hashCode
  • 當它們都被覆蓋時, equalshashCode必須使用相同的字段集
  • 如果兩個對象相等,那麼它們的hashCode值也必須相等
  • 如果對像是不可變的,則hashCode是緩存和延遲初始化的候選對象

hashCode為對象提供唯一標識符是一種流行的誤解。 它不是。

按照一般約定,Java 中的equals()方法必須是自反的、對稱的、傳遞的、一致的,並且任何非空引用都必須返回 false。 換句話說,對於 a、b 和 c 的任意值,以下測試必須始終通過:

對於最佳實踐,請使用以下步驟來實現您的 equals() 方法:

  • 使用 this == that 來檢查引用相等
  • 使用instanceof測試正確的參數類型
  • 將參數轉換為正確的類型
  • 比較重要字段是否相等

這是一個完整的例子。

CrunchifyImplementEqualsHashCode.java

Eclipse 控制台輸出: