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

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








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