為什么重寫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默認下情況比較兩個對象的地址是否相同   如果對象重寫了equals()方法,比較兩個對象的內容是否相等

但很多類都重寫了equals方法,像String,基本數據的包裝類等把他變成了值比較 所以一般情況下equals比較的是值是否相等

hashCode :hashCode() 定義也在JDK的Object.java中

hashCode() 的作用是獲取哈希碼,它實際上是返回一個int整數。這個哈希碼的作用是確定該對象在哈希表中的索引位置。

 

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作者建議的原因

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM