我們知道對於list
、map
這種底層是基於陣列的動態容器,在擴容時會進行陣列複製,因此為了避免這種額外開銷,應該盡量在建立時指定大小。
對於沒有負載因子的如list
,其擴容策略為滿了後下次插入進行擴容,因此初始化大小為需要大小即可
對於存在負載因子的hashmap
、hashset
等,其擴容策略為本次插入後並判斷自增後是否超過了閾值(容量*負載因子),如果超過了則進行擴容。因此初始化時指定的容量應為(需要的容量/負載因子+1)
距離我們有6個元素,則hashmap
的初始化容量應為(6/0.75 +1=9)
即new hashmap(9)
,實際容量為比9大的最近的2的指數即16
為什麼要+1 ?
因為擴容不是在插入前,而是在插入後進行的。如果我們不+1,指定為new hashmap(8)
,則擴容閾值為8*0.75=6
在我們插入最後乙個即第6個元素後,會進行自增6變成7,7>閾值6因此會進行擴容,而我們已經沒有元素需要新增了,從而造成額外的一次擴容操作
HashMap的初始容量機制及擴容機制
通常在我們的應用中,hashmap是用到最多的資料結構之一,在jdk1.8之前,它的底層結構是陣列 鍊錶,而在jdk1.8之後,為了查詢效率的優化 主要是當雜湊碰撞較多的時候 它的底層結構變成了陣列 鍊錶 紅黑樹。今天就來 一下hashmap的擴容機制,這也是面試時被問到最多的問題。首先看一下原始碼...
HashMap初始容量為什麼是16
這裡不講 只講思路。要稍微懂點二進位制。hashmap的結構是陣列加鍊表,容量指的是陣列長度。元素放入陣列的哪個位置?這由算出來的hashcode 跟 1111 作與運算 得出陣列下標。hashcode具體演算法我也不知道 為什麼是1111,因為0000 1111共16個數,跟陣列下標 容量都一致。...
HashMap 容量為2次冪的原因
我們都知道 hashmap 的底層是乙個陣列加鍊表的結構,當向其中新增乙個元素的時候,需要根據key的hash值,去確定其在陣列中的具體位置。看原始碼,我們可以發現,確定陣列位置的實現是i n 1 hash,其中 n 代表陣列的長度,即map的容量。當n為2的冪次方時,n 1 hash 的值是均勻分...