HashMap 采用一種算法決定每個(gè)元素的存儲(chǔ)位置。當(dāng)執(zhí)行map.put(String,Obect)方法時(shí),系統(tǒng)將調(diào)用String的hashCode()方法得到其hashCode值——每個(gè)Java對(duì)象都有hashCode()方法,都可通過該方法獲得它的hashCode值。得到這個(gè)對(duì)象的hashCode值之后,系統(tǒng)會(huì)根據(jù)該hashCode值來決定該元素的存儲(chǔ)位置。源碼中用到了一個(gè)重要的內(nèi)部接口:Map.Entry,每個(gè)Map.Entry其實(shí)就是一個(gè)key-value對(duì)。從上面程序中可以看出:當(dāng)系統(tǒng)決定存HashMap中的key-value對(duì)時(shí),完全沒有考慮Entry中的value,僅僅只是根據(jù)key來計(jì)算并決定每個(gè)Entry的存儲(chǔ)位置。

Hashmap里面的bucket出現(xiàn)了單鏈表的形式,散列表要解決的一個(gè)問題就是散列值的沖突問題,通常是兩種方法:鏈表法和開放地址法。鏈表法就是將相同hash值的對(duì)象組織成一個(gè)鏈表放在hash值對(duì)應(yīng)的槽位;開放地址法是通過一個(gè)探測(cè)算法,當(dāng)某個(gè)槽位已經(jīng)被占據(jù)的情況下繼續(xù)查找下一個(gè)可以使用的槽位。java.util.HashMap采用的鏈表法的方式,鏈表是單向鏈表。
HashMap里面沒有出現(xiàn)hash沖突時(shí),沒有形成單鏈表時(shí),hashmap查找元素很快,get()方法能夠直接定位到元素,但是出現(xiàn)單鏈表后,單個(gè)bucket里存儲(chǔ)的不是一個(gè)Entry,而是一個(gè)Entry鏈,系統(tǒng)只能必須按順序遍歷每個(gè)Entry,直到找到想搜索的Entry為止——如果恰好要搜索的Entry位于該Entry鏈的最末端(該Entry是最早放入該bucket中),那系統(tǒng)必須循環(huán)到最后才能找到該元素。








暫無數(shù)據(jù)