equals & hashCode

小樹他爹發表於2018-03-18

在密碼學中,雜湊演算法有 MD5 SHA1 SHA256 等。現在對兩個資料的二進位制內容分別做雜湊運算,如果雜湊值不同,那麼這兩個資料的二進位制內容一定不同,而如果雜湊值相同,這兩個資料的二進位制內容可能相同,也可能不同,這時就需要逐個位元位的比較兩個資料的內容,才能最終確認內容是否相同。

Java 中,那兩個資料就好比是兩個物件,hashCode() 就好比是密碼學中的雜湊運算結果,逐個位元位比對兩個資料內容是否相同,就好比是 equals() 的計算過程。

當通過 HashSetcontains() 方法判斷集合是否包含某個物件時,首先會計算該物件的 hashCode() 找到對應的 bucket,如果對應的 bucket 是空的,那麼一定不包含該物件,如果不是空的,就需要進一步通過 equals() 方法判斷物件是否確實存在。

言歸正傳,Javaequals() 代表 邏輯相等hashCode() 計算的雜湊值用於確定雜湊表中的位置,便於快速查詢。 equals hashCode 都屬於 Object 類,如果要覆蓋,必須遵守相應的約定,否則依賴這些約定的類,例如 HashMap HashSet 就無法結合該類一起正常運作。

equals 的約定如下:

  • 自反性
  • 對稱性
  • 傳遞性
  • 一致性

hashCode 的約定如下:

  • 在應用程式的執行期間,只要物件的 equals 方法的比較操作所用到的資訊沒有被修改,那麼對這同一個物件呼叫多次,hashCode 方法都必須始終如一地返回同一個證照。在同一個應用程式的多次執行過程中,每次執行所返回的整數可以不一致。
  • 如果兩個物件根據 equals 方法比較是相等的,那麼呼叫者兩個物件中任意一個物件的 hashCode 方法都必須產生相同的整數結果。
  • 如果兩個物件根據 equals 方法比較是不相等的,那麼呼叫這兩個物件中任意一個物件的 hashCode 方法,則不一定要產生不同的整數結果。但是程式設計師應該知道,給不相等的物件產生截然不同的證照結果,有可能提高雜湊表的效能。

Effective Java 提到,覆蓋 equals 時總要覆蓋 hashCode

相關文章