您好,登錄后才能下訂單哦!
HashMap中的equals和hashCode
Java的Object對象有9個方法,其中的equals()和hashCode()在hashMap的實(shí)現(xiàn)里面起著比較重要的作用,我在研究hashMap的源碼時就遇到了它們倆,此篇博文主要是為了記錄它們之間的相愛相殺。
為了說明它們的關(guān)系,我們需要HashMap的背景知識。
HashMap的存儲方式:
HashMap的實(shí)現(xiàn)方式是數(shù)組鏈,不同的對象根據(jù)其哈希碼hashCode方法的返回值)找到對應(yīng)的數(shù)組下標(biāo),然后存入數(shù)組。不同的對象有相同的哈希碼時怎么辦?這就由數(shù)組鏈中的鏈來解決了,相同哈希碼的對象都放在同一條鏈上,該鏈的鏈頭指向數(shù)組,進(jìn)而形成數(shù)組鏈。
當(dāng)?shù)谝粋€對象已經(jīng)存入HashMap,第二個對象準(zhǔn)備存入HashMap時,系統(tǒng)在查找到數(shù)組下標(biāo)后若發(fā)現(xiàn)它們的hashCode相同(數(shù)組下標(biāo)相同)(也就是沖突),會調(diào)用equals()來檢查它們之間的關(guān)系,會有相應(yīng)有以下兩種處理方法:
1. 如果相等,系統(tǒng)就不再存入第二個對象;
如果不等,系統(tǒng)視它們?yōu)榧兇獾南聵?biāo)沖突,將它們放在同一條鏈上;(拉鏈桶)
如果它們的hashCode不相同,直接存入第二個對象。
equals()匹配但hashCode()不同:會發(fā)生不可預(yù)料的事情
現(xiàn)在假設(shè)有兩個對象,它們的equals()相匹配,但hashCode()卻不同,讓我們好好分析一下當(dāng)它們存入HashMap時會發(fā)生什么。
假設(shè)StringA和StringB是兩個不同的對象,內(nèi)容都是”hello,world”,equals()返回true,但hashCode()返回值不一樣。我們把StringA和StringB當(dāng)作Key,分別對應(yīng)著ValueA和ValueB。
在StringA和ValueA已經(jīng)存入HashMap后,我們嘗試存入StringB和ValueB,因?yàn)閔ashCode不同,StringB和ValueB順利地進(jìn)入HashMap.
我們寫一個查詢:HashMap.get(“hello,world”),此時會發(fā)生什么呢?我們?nèi)』氐木烤故荲alueA還是ValueB?不可預(yù)料。
或者換一下,我們寫一個查詢:HashMap.get(StringA),此時會發(fā)生什么呢?我們?nèi)』氐木烤故荲alueA還是ValueB?不可預(yù)料。
再換一下,我們寫一個查詢:HashMap.get(StringB),此時會發(fā)生什么呢?我們?nèi)』氐木烤故荲alueA還是ValueB?不可預(yù)料。
所以我們常說,如果equals匹配,hashCode()一定要相同,不然就有神奇的事情發(fā)生。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。