首先要了解HashMap的擴(kuò)容過(guò)程,我們就得了解一些HashMap中的變量:
Node<K,V>:鏈表節(jié)點(diǎn)词裤,包含了key刺洒、value、hash吼砂、next指針?biāo)膫€(gè)元素
table:Node<K,V>類型的數(shù)組逆航,里面的元素是鏈表,用于存放HashMap元素的實(shí)體
size:記錄了放入HashMap的元素個(gè)數(shù)
loadFactor:負(fù)載因子
threshold:擴(kuò)容的閾值渔肩,決定了HashMap何時(shí)擴(kuò)容因俐,以及擴(kuò)容后的大小,一般等于周偎,等于 table * loadFactor
何時(shí)進(jìn)行擴(kuò)容抹剩?
HashMap使用的是懶加載,構(gòu)造完HashMap對(duì)象后蓉坎,只要不進(jìn)行put 方法插入元素之前澳眷,HashMap并不會(huì)去初始化或者擴(kuò)容table。
當(dāng)首次調(diào)用put方法時(shí)蛉艾,HashMap會(huì)發(fā)現(xiàn)table為空然后調(diào)用resize方法進(jìn)行初始化
钳踊,當(dāng)添加完元素后,如果HashMap發(fā)現(xiàn)size(元素總數(shù))大于threshold(閾值)勿侯,則會(huì)調(diào)用resize方法進(jìn)行擴(kuò)容
擴(kuò)容過(guò)程:
- 若threshold(閾值)不為空拓瞪,table的首次初始化大小為閾值,否則初始化為缺省值大小16
- 默認(rèn)的負(fù)載因子大小為0.75罐监,當(dāng)一個(gè)map填滿了75%的bucket時(shí)候吴藻,就會(huì)擴(kuò)容,擴(kuò)容后的table大小變?yōu)樵瓉?lái)的兩倍
- 假設(shè)擴(kuò)容前的table大小為2的N次方弓柱,有上述put方法解析可知沟堡,元素的table索引為其hash值的后N位確定
- 擴(kuò)容后的table大小即為2的N+1次方,則其中元素的table索引為其hash值的后N+1位確定矢空,比原來(lái)多了一位
- 重新調(diào)整map的大小航罗,并將原來(lái)的對(duì)象放入新的bucket數(shù)組中。這個(gè)過(guò)程叫作rehashing
因此屁药,table中的元素只有兩種情況:
元素hash值第N+1位為0:不需要進(jìn)行位置調(diào)整
元素hash值第N+1位為1:調(diào)整至原索引的兩倍位置
擴(kuò)容或初始化完成后粥血,resize方法返回新的table
技術(shù)討論 & 疑問(wèn)建議 & 個(gè)人博客
版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 CC BY-NC-SA 3.0 許可協(xié)議,轉(zhuǎn)載請(qǐng)注明出處复亏!