请你解释一下HashMap具体如何实现的?
請(qǐng)你解釋一下HashMap具體如何實(shí)現(xiàn)的?
HashMap是基于數(shù)組+鏈表實(shí)現(xiàn)的,通過對(duì)key的hashcode & 數(shù)組的長(zhǎng)度=得到在數(shù)組中的位置,如果當(dāng)前數(shù)組有元素,則將數(shù)組的當(dāng)前元素的next指向要插入的新元素,這樣用于解決哈希沖突,形成了拉鏈?zhǔn)降慕Y(jié)構(gòu)。
put時(shí)在多線程的情況下,會(huì)形成環(huán)從而導(dǎo)致死循環(huán)。
數(shù)組長(zhǎng)度一般是2n,從0開始編號(hào),所以hashcode & (2n-1),(2n-1)每一位都是1,這樣會(huì)讓散列均勻。需要注意的是,HashMap在JDK1.8時(shí)引入了紅黑樹結(jié)構(gòu)進(jìn)行優(yōu)化,當(dāng)鏈表元素個(gè)數(shù)>=8時(shí),鏈表將轉(zhuǎn)化為樹結(jié)構(gòu);若桶中鏈表元素個(gè)數(shù)<=6時(shí),樹結(jié)構(gòu)還原成鏈表。因?yàn)榧t黑樹的平均查找時(shí)間復(fù)雜度是lgN,長(zhǎng)度為8的時(shí)候,平均查找長(zhǎng)度為3,如果繼續(xù)使用鏈表,平均查找長(zhǎng)度為8/2=4,這才有轉(zhuǎn)換為樹的必要。鏈表長(zhǎng)度如果<=6,6/2=3,雖然速度也很快,但是轉(zhuǎn)換為樹結(jié)構(gòu)和生成樹的時(shí)間并不會(huì)太短。還有選擇6和8,中間有個(gè)差值7可以有效防止鏈表和樹頻繁轉(zhuǎn)換。假設(shè)一下,如果設(shè)計(jì)成鏈表元素個(gè)數(shù)超過8則鏈表轉(zhuǎn)換為樹結(jié)構(gòu),鏈表元素個(gè)數(shù)小于8則樹結(jié)構(gòu)轉(zhuǎn)換成鏈表,如果一個(gè)HashMap不停的插入、刪除元素,鏈表個(gè)數(shù)在8左右徘徊,就會(huì)頻繁地發(fā)生鏈表轉(zhuǎn)樹,樹轉(zhuǎn)鏈表,效率就會(huì)很低。
總結(jié)
以上是生活随笔為你收集整理的请你解释一下HashMap具体如何实现的?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 请你说明一下TreeMap的底层实现?
- 下一篇: 请你简单介绍一下ArrayList和Li