為什麼重寫equals()就要重寫hashcode()
阿里巴巴開發規範
只要重寫 equals,就必須重寫 hashCode
因為 Set 儲存的是不重複的物件,依據 hashCode 和 equals 進行判斷,所以 Set 儲存的物件必須重寫這兩個方法
如果自定義物件做為 Map 的鍵,那麼必須重寫 hashCode 和 equals
Object作者建議
相同的物件必然是相同的雜湊值,不同的雜湊值是不同的物件
在開發規範和Object作者建議中都是隻要重寫 equals, 就必須重寫 hashCode為什麼?
要明白重寫equals的原因要先明白equals是什麼,與之關聯的 ==,hashCode又是什麼?
== :是對於基本資料型別的值比較
equals :定義在JDK的Object.java中這就意味著Java中的任何類都包含有equals()函式
equals
hashCode() 和 equals() 有什麼關係?
有關係,但不能說完全有關係 以“類的用途”分2種情況來說明
類對應的散列表(散列表就是同時運用了陣列和連結串列如 HashMap,HashSet,HashTable等這些本質是散列表的資料結構中)
1 不會建立“類對應的散列表”
在這種情況下,該類的“hashCode() 和 equals() ”是沒有任何關係的 equals() 用來比較該類的兩個物件是否相等,而hashCode() 則根本沒有任何作用
可以看到equals是相等的,但hashCode值是不同的,在這種情況下hashCode值是沒有任何作用的
2 會建立“類對應的散列表”
在這種情況下,該類的“hashCode() 和 equals() ”是有關係的:如果兩個物件相等,那麼它們的hashCode()值一定相同。
這裡的相等是指,通過equals()比較兩個物件時返回true。
如果兩個物件hashCode()相等,它們並不一定相等。因為在散列表中,hashCode()相等,即兩個鍵值對的雜湊值相等。
然而雜湊值相等,並不一定能得出鍵值對相等,此時就出現所謂的雜湊衝突場景。也就是Set 儲存的是不重複的物件
(hashSet底層是hashMap)
所以說在散列表中 如果重寫了 equals() 而未重寫 hashcode() 方法,可能就會出現兩個沒有關係的物件 equals 相同
(因為equal都是根據物件的特徵進行重寫的),但 hashcode 不相同的情況, 因為在散列表資料結構中要保持key值的唯一,
不然會進行覆蓋,通過equals來比較兩個key是否相同,也能達到要求,只不過就要和map中的key一個一個的用equals比較,
如果map中有很多元素了,那麼效率可能會很低,hashCode方法是根據物件的記憶體地址經過雜湊演算法(資料壓縮技術,儘量分散
減少雜湊衝突)得來的 使用hashCode的一個目的是“分組”,同一個連結串列上的key的 hashcode是一樣的,如果不重寫hashcode,
那麼兩個相同內容的物件,就會放在不同的連結串列上,那麼就會存在兩個相同的key。所以就要重寫hashcode,
保證有相同內容的物件有相同的hashcode。而且hashcode的結果跟物件的屬性有關。如果屬性不參與hashcode的計算,
那麼這個hash演算法就無意義。
如果自定義物件做為 Map 的鍵,那麼必須重寫 hashCode 和 equals
這個就是開發規範和Object作者建議的原因