阿里巴巴開發規范
只要重寫 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作者建議的原因