面試題:我們重寫一個對象的時候爲什麼要同時重寫hashcode()和equals()方法

個人博客網:https://wushaopei.github.io/ (你想要這裏多有)

在創建的類不重寫hashCode()和equals() 方法時,默認使用 java 提供的 java.lang.Object 下的 hashCode()和equals() 方法。

注意:Object 的public boolean equals(Object obj)方法主要是對非空對象的引用地址的判斷相同才返回true,而非對象本身的字符串內容或數值是否相同。

簡而言之,當且僅當 值A 和 值B 都是引用自同一個對象時,此方法纔會返回true;

所以,當我們重寫一個對象,重寫了equals()方法後,通常必須重寫 hashCode()方法,以維護 hashCode 方法的常規協定,該協定聲明瞭相等對象必須具有相等的哈希碼。

說白了,就是equals 返回true的兩個值,在hashCode() 中結果也必然是true。

例子:
(1)當obj1.equals(obj2)爲true時,obj1.hashCode() == obj2.hashCode()必須爲true
(2)當obj1.hashCode() == obj2.hashCode()爲false時,obj1.equals(obj2)必須爲false

這裏引出一個問題,爲什麼要重寫equals()方法呢?難道原生的不能用嗎?

答案是必須重寫,從前面的注意事項中可以知道,如果不重寫equals 方法,那麼比較的將是對象的引用是否指向同一塊內存地址,而我們重寫的目的是爲了能夠比較兩個對象的value值是否相等。

在高級類的八個包裝類與引用類型的String類型(該類對euqals和hashcode方法進行了重寫)中都 是使用重寫後的 equals 方法來比較對象的,默認比較的是值,在比較其它自定義對象時都是比較的引用地址。

後面會對equals 和 hashcode 的關係進行關聯解釋。

hashcode是用於散列數據的快速存取,如利用HashSet/HashMap/Hashtable類來存儲數據時,都是根據存儲對象的hashcode值來進行判斷是否相同的。

那麼,如果我們值重寫equals ,而不重寫 hashcode 會怎麼樣?

如果我們對一個對象重寫了equals 方法,意味着只要對象的成員變量值都相等那麼equals 就返回true ,但在不重寫 hashcode 方法的情況下,當我們重新 new 了一個新對象。
此時,當原對象.equals(新對象)等於true時,兩者的 hashcode 卻是不一樣的,由此會產生了理解的不一致,也違反了equals 與 hashcode的約定規則。

不重寫導致的結果案例:

在不重寫hashcode的情況下,如果 hashset存儲兩個引用不同但值相同的對象,此時hashcode返回false,認爲後者與前者不重複,則會重新 newNode() 創建一個新節點將重複的值添加到集合中,意味着不可重複的單列集合中出現了兩個值一樣的對象,導致混淆。(假設沒有重寫)

所以,需要重寫 hashcode()方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章