1. 程式人生 > 其它 >為什麼重寫equal方法的時候要重寫hashcode()方法?

為什麼重寫equal方法的時候要重寫hashcode()方法?

面試官可能會問你:

“你重寫過 hashCode() 和 equals()麼?為什麼重寫 equals() 時必須重寫 hashCode() 方法?”

 

hashCode() 有什麼用?

hashCode() 的作用是獲取雜湊碼(int 整數),也稱為雜湊碼。這個雜湊碼的作用是確定該物件在雜湊表中的索引位置。

hashCode()定義在 JDK 的 Object 類中,這就意味著 Java 中的任何類都包含有 hashCode() 函式。另外需要注意的是: Object 的 hashCode() 方法是本地方法,也就是用 C 語言或 C++ 實現的,該方法通常用來將物件的記憶體地址轉換為整數之後返回。

 

為什麼要有 hashCode?

我們以“HashSet 如何檢查重複”為例子來說明為什麼要有 hashCode

下面這段內容摘自我的 Java 啟蒙書《Head First Java》:

當你把物件加入 HashSet 時,HashSet 會先計算物件的 hashCode 值來判斷物件加入的位置,同時也會與其他已經加入的物件的 hashCode 值作比較,如果沒有相符的 hashCodeHashSet 會假設物件沒有重複出現。但是如果發現有相同 hashCode 值的物件,這時會呼叫 equals() 方法來檢查 hashCode 相等的物件是否真的相同。如果兩者相同,HashSet

 就不會讓其加入操作成功。如果不同的話,就會重新雜湊到其他位置。這樣我們就大大減少了 equals 的次數,相應就大大提高了執行速度。

其實, hashCode() 和 equals()都是用於比較兩個物件是否相等

 

那為什麼 JDK 還要同時提供這兩個方法呢?

這是因為在一些容器(比如 HashMapHashSet)中,有了 hashCode() 之後,判斷元素是否在對應容器中的效率會更高(參考新增元素進HastSet的過程)!

我們在前面也提到了新增元素進HastSet的過程,如果 HashSet 在對比的時候,同樣的 hashCode 有多個物件,它會繼續使用 equals() 來判斷是否真的相同。也就是說 hashCode

 幫助我們大大縮小了查詢成本。

 

那為什麼不只提供 hashCode() 方法呢?

這是因為兩個物件的hashCode 值相等並不代表兩個物件就相等。

那為什麼兩個物件有相同的 hashCode 值,它們也不一定是相等的?

因為 hashCode() 所使用的雜湊演算法也許剛好會讓多個物件傳回相同的雜湊值。越糟糕的雜湊演算法越容易碰撞,但這也與資料值域分佈的特性有關(所謂雜湊碰撞也就是指的是不同的物件得到相同的 hashCode )。

總結下來就是 :

  • 如果兩個物件的hashCode 值相等,那這兩個物件不一定相等(雜湊碰撞)。
  • 如果兩個物件的hashCode 值相等並且equals()方法也返回 true,我們才認為這兩個物件相等。
  • 如果兩個物件的hashCode 值不相等,我們就可以直接認為這兩個物件不相等。

 

為什麼重寫equal方法的時候要重寫hashcode()方法?

其實不一定的,只是許多容器類,如 HashMap、HashSet 都依賴於 hashcode 與 equals 的規定。

為什麼需要重寫hashcode()方法?

​由於在hashMap中在put時,雜湊函式根據它的雜湊值找到對應的位置,如果該位置有元素,首先會使用hashCode方法判斷,如果沒有重寫hashCode方法,那麼即使倆個物件屬性相同hashCode方法也會認為他們是不同的元素,又因為Set是不可以有重複的,所以這會產生矛盾,那麼就需要重寫hashCode方法。