== 與 equals的區別
如果兩個引用類型變量使用==運算符,那麼比較的是地址,它們分別指向的是否是同一地址的對象。結果一定是false,因為兩個對象不可能存放在同一地址處。要求是兩個對象都不是能空值,與空值比較返回false。==不能實現比較對象的值是否相同。所有對象都有equals方法,默認是Object類的equals,其結果與==一樣。如果希望比較對象的值相同,必須重寫equals方法。hashCode與equals的區別
Object中的equals:
equals 方法要求滿足:
自反性 a.equals(a)對稱性 x.equals(y) y.equals(x)一致性 x.equals(y) 多次調用結果一致對於任意非空引用x,x.equals(null) 應該返回falseObject中的hashCode:
它是一個本地方法,它的實現與本地機器有關,這裡我們暫且認為他返回的是對象存儲的物理位置。
當equals方法被重寫時,通常有必要重寫hashCode方法,以維護hashCode方法的常規約定:值相同的對象必須有相同的hashCode。object1.equals(object2)為true,hashCode也相同;hashCode不同時,object1.equals(object2)為false;hashCode相同時,object1.equals(object2)不一定為true;當我們向一個Hash結構的集合中添加某個元素,集合會首先調用hashCode方法,這樣就可以直接定位它所存儲的位置,若該處沒有其他元素,則直接保存。若該處已經有元素存在,就調用equals方法來匹配這兩個元素是否相同,相同則不存,不同則鏈到後面(如果是鏈地址法)。
先調用hashCode,唯一則存儲,不唯一則再調用equals,結果相同則不再存儲,結果不同則散列到其他位置。因為hashCode效率更高(僅為一個int值),比較起來更快。
HashMap#put源碼
hash是key的hash值,當該hash對應的位置已有元素時會執行以下代碼(hashCode相同)
如果equals返回結果相同,則值一定相同,不再存入。
如果重寫equals不重寫hashCode會怎樣
兩個值不同的對象的hashCode一定不一樣,那麼執行equals,結果為true,HashSet或HashMap的鍵會放入值相同的對象。
話不多說,直接上例子,~~~
首先我們只重寫equals()方法
看我們的測試類
依次輸出
是否出現矛盾???用equals比較說明對象相同,但是在HashMap中卻以不同的對象存儲(沒有重寫hascode值,兩個hascode值,在他看來就是兩個對象)。到底這兩個對象相等不相等????說明必須重寫hashCode()的重要性,
接下來重寫重寫equals方法和hashCode方法,再比較
測試類
依次輸出
看到這裡,同學 你懂了嗎?還不懂,可以自己實現一遍代碼。