1. 程式人生 > 其它 >為什麼重寫equals()就要重寫hashcode()

為什麼重寫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作者建議的原因