HashMap 为什么在链表长度为 8 的时候转红黑树,为啥不能是 9 是 10?
這個(gè)問題是在面試某公司的時(shí)候面試官提的問題,當(dāng)時(shí)沒回答上來。歸根到底還是因?yàn)樽约簭?fù)習(xí)基礎(chǔ)的時(shí)候還不夠仔細(xì),也缺乏思考。
首先
我覺得需要確認(rèn)一下,是不是隨便什么情況下只要滿足了鏈表長度為8就轉(zhuǎn)紅黑樹呢?答案自然不是,為什么不是,看代碼:
/*** Replaces all linked nodes in bin at index for given hash unless* table is too small, in which case resizes instead.*/final void treeifyBin(Node<K,V>[] tab, int hash) {int n, index; Node<K,V> e;if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)resize();......}這是HashMap轉(zhuǎn)紅黑樹的方法代碼,可以看到,如果此時(shí)的HashMap的長度是小于MIN_TREEIFY_CAPACITY的或者為空,則進(jìn)行擴(kuò)容操作,而不是轉(zhuǎn)紅黑樹,這其實(shí)也是容易忽略的點(diǎn)。
為什么要轉(zhuǎn)紅黑樹?
回答自然很簡單,因?yàn)殒湵硎侨∫粋€(gè)數(shù)需要遍歷鏈表,復(fù)雜度為O(N),而紅黑樹為O(logN)唄,那么問題來了
為什么不直接使用紅黑樹,而是要先使用鏈表實(shí)在不行再轉(zhuǎn)紅黑樹呢?
答案自然要在源碼和注釋里找:在HashMap類中第174行左右有描述:
Because TreeNodes are about twice the size of regular nodes, weuse them only when bins contain enough nodes to warrant use(see TREEIFY_THRESHOLD)“因?yàn)闃涔?jié)點(diǎn)的大小是鏈表節(jié)點(diǎn)大小的兩倍,所以只有在容器中包含足夠的節(jié)點(diǎn)保證使用才用它”,顯然盡管轉(zhuǎn)為樹使得查找的速度更快,但是在節(jié)點(diǎn)數(shù)比較小的時(shí)候,此時(shí)對于紅黑樹來說內(nèi)存上的劣勢會(huì)
超過查找等操作的優(yōu)勢,自然使用鏈表更加好,但是在節(jié)點(diǎn)數(shù)比較多的時(shí)候,綜合考慮,紅黑樹比鏈表要好。
為什么是8,而不是9不是10?
其實(shí)當(dāng)時(shí)想回答面試官這是基于統(tǒng)計(jì)的結(jié)果,但是心里很虛還是沒有說,再回頭看看源碼的描述:
Ideally, under random hashCodes, the frequency of nodes in bins follows a Poisson distribution with a parameter of about 0.5 on average for the default resizing threshold of 0.75, although with a large variance because of resizing granularity. Ignoring variance, the expected occurrences of list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The first values are:0: 0.606530661: 0.303265332: 0.075816333: 0.012636064: 0.001579525: 0.000157956: 0.000013167: 0.000000948: 0.00000006more: less than 1 in ten million理想情況下,在隨機(jī)哈希碼下,哈希表中節(jié)點(diǎn)的頻率遵循泊松分布,而根據(jù)統(tǒng)計(jì),忽略方差,列表長度為K的期望出現(xiàn)的次數(shù)是以上的結(jié)果,可以看到其實(shí)在為8的時(shí)候概率就已經(jīng)很小了,再往后調(diào)整并沒有很大意義。
更多 Java 原創(chuàng)文章,請關(guān)注我微信公眾號 「Java中文社群」
總結(jié)
以上是生活随笔為你收集整理的HashMap 为什么在链表长度为 8 的时候转红黑树,为啥不能是 9 是 10?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 史上最详细nodejs版本管理器nvm的
- 下一篇: 聊一聊开发常用小工具