個人博客網: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()方法。
