整理了一些關於hashmap的面試題。
爲什麼在鏈式長度爲8的時候才構建紅黑樹
長度爲8,鏈表轉樹,長度爲6,樹轉鏈表。。中間有個差值,還可以防止鏈表和樹頻繁轉換。假設8以上轉爲樹,8以下轉爲鏈表,那麼一個hashmap如果不停的插入刪除,鏈表長度在8左右徘徊,就會不停的樹轉鏈表,鏈表轉樹,效率很低。
hashmap 爲什麼要2的n次冪長度
接下來,我們分析下爲什麼哈希表的容量一定要是2的整數次冪。首先,length爲2的整數次冪的話,h&(length-1)就相當於對length取模,這樣便保證了散列的均勻,同時也提升了效率;其次,length爲2的整數次冪的話,爲偶數,這樣length-1爲奇數,奇數的最後一位是1,這樣便保證了h&(length-1)的最後一位可能爲0,也可能爲1(這取決於h的值),即與後的結果可能爲偶數,也可能爲奇數,這樣便可以保證散列的均勻性,而如果length爲奇數的話,很明顯length-1爲偶數,它的最後一位是0,這樣h&(length-1)的最後一位肯定爲0,即只能爲偶數,這樣任何hash值都只會被散列到數組的偶數下標位置上,這便浪費了近一半的空間,因此,length取2的整數次冪,是爲了使不同hash值發生碰撞的概率較小,這樣就能使元素在哈希表中均勻地散列。
indexFor爲什麼用 h & (length-1)
static int indexFor(int h, int length) { //根據hash值和數組長度算出索引值
return h & (length-1);
}
這個我們要重點說下,我們一般對哈希表的散列很自然地會想到用hash值對length取模(即除法散列法),Hashtable中也是這樣實現的,這種方法基本能保證元素在哈希表中散列的比較均勻,但取模會用到除法運算,效率很低,HashMap中則通過h&(length-1)的方法來代替取模,同樣實現了均勻的散列,但效率要高很多,這也是HashMap對Hashtable的一個改進。