不同時重寫equals和hashCode又會怎樣?
如果問到 == 和 equals 的區別,相信很多https://www.b5b6.com同學都能脫口而出:一個是判斷地址,一個是判斷內容。
但是如果繼續追問:“你重寫過 equals 么?”,“重寫 equals 方法的時候,必須重寫 hashCode 方法么?”,“不同時重寫equals和hashCode又會怎樣?”
你還能信心滿滿地回答上來么?
== 與 equals1. ==
如果比較的是兩個基本數據類型,那么 == 比較的是值;如果是兩個非基本數據類型的對象,那就是判斷它們的內存地址是不是相同;
2. equals
如果類沒有覆蓋 equals 方法,那么 equals 等價于 == ;如果覆蓋了 equals 方法,那么就需要根據 equals 方法的邏輯來判斷兩個對象是否相等。讓我們看看 String 中的 equals 方法是什么樣的:
我們可以看到 String 的比較,是先比較內存地址,如果兩個字符串指向的地址不一樣,那么再比較兩個字符串的值。
正確使用 equals 方法我們在使用 equals 方法的時候,容易發生空指針異常,所以在使用前需要判斷對象是否為 null,或者用常量來調用 equals:
另外大家也可以使用 java.util.Objects 中的 equals 方法:
從這個方法的源碼中可以看出,方法已經幫我們考慮到控制值的問題了,所以可以放心使用。
覆蓋 equals 方法的準則自反性:對于任何非空引用值 A,A.equals(A) 返回 true。對稱性:對于任何非空引用值 A 和 B,A.equals(B) 和 B.equals(A) 的結果相同。傳遞性:對于任何非空引用值 A、B 和 C,如果 A.equals(B) 返回 true, A.equals(C) 返回 true,那么 B.equals(C) 也是 true。一致性:對于任何非空引用值 A 和 B,每一次調用 x.equals(y) 的結果是相同的。非空性:對于任何非空引用值 A,A.equals(null) 應返回 false。equals() 與 hashCode()hashCode() 方法是獲取 hash 碼(哈希碼、散列碼),我們可以把它看做返回一個 int 整數;hash 碼的作用是確定對象在散列結構中的位置。
hashCode() 方法存在于 Object 類中,代表 Java 中的任何類都會有 hashCode() 方法,那么任何場景下 hashCode() 都會產生作用么?其實并不是!
如果對象會被放入散列結構中使用,那么 hashCode() 就會起作用。
比如,當我們要向 HashMap 中放入一組 key-value 的時候,那么 HashMap 會先根據 key 對象的 hashCode 值判斷存入的位置,如果 key 存入的位置上已經有了一個元素,再根據 equals() 方法判斷兩個元素是否相等;如果確認相等,那么會覆蓋原來的 key-value 。
這時候,equals() 與 hashCode() 就是有關系的:
兩個對象 equals() 返回 true 的時候,那它們的 hashCode() 值需要相等;如果兩個對象的 hashCode() 值相等,那它們 equals() 不一定是 true;(哈希沖突)所以在這種情況下,如果要判斷兩個對象是否相等,除了要覆蓋 equals() ,也要覆蓋 hashCode(),否則就會發生意料之外的問題。當然,如果對象不會放入散列表中使用,那么 equals() 與 hashCode() 其實也沒啥關系。
我將持續分享Java開發、架構設計、https://www.b5b6.com職業發展等方面的見解,希望能得到你的關注;關注我后,可私信發送數字【1】,獲取學習資料。