在密碼學中,雜湊演算法有 MD5
SHA1
SHA256
等。現在對兩個資料的二進位制內容分別做雜湊運算,如果雜湊值不同,那麼這兩個資料的二進位制內容一定不同,而如果雜湊值相同,這兩個資料的二進位制內容可能相同,也可能不同,這時就需要逐個位元位的比較兩個資料的內容,才能最終確認內容是否相同。
在 Java
中,那兩個資料就好比是兩個物件,hashCode()
就好比是密碼學中的雜湊運算結果,逐個位元位比對兩個資料內容是否相同,就好比是 equals()
的計算過程。
當通過 HashSet
的 contains()
方法判斷集合是否包含某個物件時,首先會計算該物件的 hashCode()
找到對應的 bucket
,如果對應的 bucket
是空的,那麼一定不包含該物件,如果不是空的,就需要進一步通過 equals()
方法判斷物件是否確實存在。
言歸正傳,Java
中 equals()
代表 邏輯相等,hashCode()
計算的雜湊值用於確定雜湊表中的位置,便於快速查詢。
equals
hashCode
都屬於 Object
類,如果要覆蓋,必須遵守相應的約定,否則依賴這些約定的類,例如 HashMap
HashSet
就無法結合該類一起正常運作。
equals
的約定如下:
- 自反性
- 對稱性
- 傳遞性
- 一致性
hashCode
的約定如下:
- 在應用程式的執行期間,只要物件的
equals
方法的比較操作所用到的資訊沒有被修改,那麼對這同一個物件呼叫多次,hashCode
方法都必須始終如一地返回同一個證照。在同一個應用程式的多次執行過程中,每次執行所返回的整數可以不一致。 - 如果兩個物件根據
equals
方法比較是相等的,那麼呼叫者兩個物件中任意一個物件的hashCode
方法都必須產生相同的整數結果。 - 如果兩個物件根據
equals
方法比較是不相等的,那麼呼叫這兩個物件中任意一個物件的hashCode
方法,則不一定要產生不同的整數結果。但是程式設計師應該知道,給不相等的物件產生截然不同的證照結果,有可能提高雜湊表的效能。
Effective Java 提到,覆蓋 equals
時總要覆蓋 hashCode