1. 程式人生 > 實用技巧 >為什麼重寫equals方法必須重寫hashcode方法?

為什麼重寫equals方法必須重寫hashcode方法?

首先,我們先了解一下Object中的equals方法:

public boolean equals(Object obj)

對於任何非空引用值 x 和 y,當且僅當 x 和 y 引用同一個物件時,此方法才返回 true;

即object類中的equals方法其實判斷的不是值是否相等,而是必須是同一個物件才會返回true。

假如自定義一個類,如果不重寫equals,由於Object類是所有類的父類,呼叫equals時判斷的是物件的引用是否指向同一塊記憶體地址,而重寫的目的是為了比較兩個物件的value值是否相等

接下來說說hashcode方法:

hashCode()方法:

此方法返回物件的雜湊碼值,什麼是雜湊碼?
雜湊碼產生的依據:雜湊碼並不是完全唯一的,它是一種演算法,讓同一個類的物件按照自己不同的特徵儘量的有不同的雜湊碼,但不表示不同的物件雜湊碼完全不同。

hashcode是用於雜湊資料的快速存取,當利用HashSet/HashMap/Hashtable類來儲存資料時,都是根據儲存物件的hashcode值來進行判斷是否相同的。

簡單理解就是一套演算法算出來的一個值,且這個值對於這個物件相對唯一。所以如果兩個物件相等,他們的hashcode一定相等。反正則不一定。

要說清楚為什麼重寫equals方法必須重寫hashcode方法,需要先了解一下集合中是如何檢查重複元素?

當你把物件加⼊ HashSet時,HashSet 會先計算物件的 hashcode 值來判斷物件加⼊的位置,同時也會與該位置其他已經加⼊的物件的 hashcode 值作比較,如果沒有相符的 hashcode,HashSet 會假設物件沒有重複出現。

但是如果發現有相同 hashcode 值的物件,這時會調⽤ equals() ⽅法來檢查 hashcode 相等的物件是否真的相同。如果兩者相同,HashSet 就不會讓其加⼊操作成功。如果不同的話,就會重新雜湊到其他位置。

所以當equals方法被重寫時,需要重寫 hashCode 方法,以維護 hashCode 方法的常規協定,該協定宣告相等物件必須具有相等的雜湊碼。如下:

(1)當obj1.equals(obj2)為true時,obj1.hashCode() == obj2.hashCode()必須為true
(2)當obj1.hashCode() == obj2.hashCode()為false時,obj1.equals(obj2)必須為false

假如不重寫會出現什麼情況呢?

如果我們對一個物件重寫了euqals,意思是隻要物件的成員變數值都相等那麼euqals就等於true,但不重寫hashcode
那麼我們當再new一個新的物件時,當原物件.equals(新物件)等於true時,此時兩者的hashcode卻是不一樣的,這就會出現以下問題:
當我們把這個物件加入到儲存雜湊集合中時(如Set類),將會儲存了兩個值一樣的物件,導致混淆,因此,就也需要重寫hashcode()