面試爛的hashMap你真的懂嗎?

前言:HashMap是java工程師在面試過程中,碰到的概率極大的一道題,很大一部分人都是看了一些博客,記住一些答案,但是深究往往無法接招,本文就來扒一扒hashMap面試常見的點及源碼分析。

推薦分析目前爲止個人看過的分析hashMap比較好的文章。
Java 8系列之重新認識HashMap
沒有閱讀過的同學,可以先看一下這篇文章,對於hashMap的設計及原理有一個大概的瞭解,一遍不行;讀兩遍。

1、hashMap中提到了“當鏈表長度大於8時,鏈表默認轉化爲紅黑樹”,爲什麼鏈表長度爲8的時候轉化呢?

答:如果節點數量比較少遍歷鏈表速度也很快,沒必要轉成樹,而且樹還要多佔空間,那麼如何定一個臨界值呢?根據泊松分佈節點相同次數超過8個節點的概率大概是百萬分之一,再記錄增加概率也不會降低太多,最終得到一個臨界值是8,也就是說插入到hashMap中節點,真正需要轉化爲紅黑樹的其實是很少的情況。

我們可以看一下源碼做的統計:

	*
	* 0:    0.60653066
	* 1:    0.30326533
	* 2:    0.07581633
	* 3:    0.01263606
	* 4:    0.00157952
	* 5:    0.00015795
	* 6:    0.00001316
	* 7:    0.00000094
	* 8:    0.00000006
	* more: less than 1 in ten million
	*

2、我們知道隨着同一個槽中節點的減少,紅黑樹可能會退化成鏈表,jdk中定義了該值爲6,爲什麼定義爲6,而不是7呢?

/**
  * 當紅黑樹元素個數小於6的時候,會從新退化爲鏈表。爲什麼?效率。
  */
static final int UNTREEIFY_THRESHOLD = 6;

答:鏈表查找的時間複雜度=O(n/2)O(n/2),紅黑樹的查找時間複雜度是O(logn)O(logn),當n=8,紅黑樹的時間是2,鏈表的時間是4,紅黑樹優於鏈表。當n=6,鏈表查詢時間是3,紅黑樹是2.585,紅黑樹基本已經沒什麼優勢了,其實對於7也沒什麼優勢,但是如果選擇7會導致鏈化和樹化頻繁切換,所以間隔調兩個元素。5、6同理,但是總得敲定一個數呀。

3、爲什麼hashMap在擴容的時候,容量大小必須是2n2^n呢?
HashMap採用這種非常規設計,主要是爲了在取模和擴容時做優化,同時爲了減少衝突,HashMap定位哈希桶索引位置時,也加入了高位參與運算的過程。
擴容的時候,可以做到元素的新位置要麼是在原位置,要麼是在原位置再移動2次冪的位置
hash值新增的那個bit是1還是0就好了,是0的話索引沒變,是1的話索引變成“原索引+oldCap”

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