JDK8中HashMap鏈表轉紅黑樹的閾值爲什麼選8?爲什麼用紅黑樹做優化?

爲什麼會引入紅黑樹做查詢優化呢?

在平常我們用HashMap的時候,HashMap裏面存儲的key是具有良好的hash算法的key(比如String、Integer等包裝類),衝突機率自然微乎其微,此時鏈表幾乎不會轉化爲紅黑樹,但是當key爲我們自定義的對象時,我們可能採用了不好的hash算法,使HashMap中key的衝突率極高但是這時HashMap爲了保證高速的查找效率,就引入了紅黑樹來優化查詢了。

爲什麼樹化的臨界值爲8?

通過源碼我們得知HashMap源碼作者通過泊松分佈算出,當桶中結點個數爲8時,出現的機率是億分之6的,因此常見的情況是桶中個數小於8的情況,此時鏈表的查詢性能和紅黑樹相差不多,因爲轉化爲樹還需要時間和空間,所以此時沒有轉化成樹的必要。

既然個數爲8時發生的機率這麼低,我們爲什麼還要當鏈表個數大於8時來樹化來優化這幾乎不會發生的場景呢?

首先我們要知道億分之6這個幾乎不可能的概率是建立在什麼情況下的 答案是:建立在良好的hash算法情況下,例如String,Integer等包裝類的hash算法、如果一旦發生桶中元素大於8,說明是不正常情況,可能採用了衝突較大的hash算法,此時桶中個數出現超過8的概率是非常大的,可能有n個key衝突在同一個桶中,此時再看鏈表的平均查詢複雜度和紅黑樹的時間複雜度,就知道爲什麼要引入紅黑樹了,

舉個例子,若hash算法寫的不好,一個桶中衝突1024個key,使用鏈表平均需要查詢512次,但是紅黑樹僅僅10次,紅黑樹的引入保證了在大量hash衝突的情況下,HashMap還具有良好的查詢性能

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章