HashMap的負載因子

2021-08-11 15:05:18 字數 2238 閱讀 3287

下面是hashmap的乙個建構函式,兩個引數initialcapacity,loadfactor

這關係hashmap的迭代效能。

/**

* constructs an empty hashmap with the specified initial

* capacity and load factor.

** @param initialcapacity the initial capacity

* @param loadfactor the load factor

* @throws illegalargumentexception if the initial capacity is negative

* or the load factor is nonpositive

*/public hashmap(int initialcapacity, float loadfactor)

關於這兩個引數值的設定界限:

1. initialcapacity是map的初始化容量,initialcapacity > maximum_capacity,表明map的最大容量是1<<30,也就是1左移30位,每左移一位乘以2,所以就是1*2^30=1073741824.

2. loadfactor是map的負載因子,loadfactor <= 0 || float.isnan(loadfactor),表明負載因子要大於0,且是非無窮大的數字

負載因子為什麼會影響hashmap效能

首先回憶hashmap的資料結構,

我們都知道有序陣列儲存資料,對資料的索引效率都很高,但是插入和刪除就會有效能瓶頸(回憶arraylist),

鍊錶儲存資料,要一次比較元素來檢索出資料,所以索引效率低,但是插入和刪除效率高(回憶linkedlist),

兩者取長補短就產生了雜湊雜湊這種儲存方式,也就是hashmap的儲存邏輯.

而負載因子表示乙個雜湊表的空間的使用程度,有這樣乙個公式:initailcapacity*loadfactor=hashmap的容量。

所以負載因子越大則雜湊表的裝填程度越高,也就是能容納更多的元素,元素多了,鍊錶大了,所以此時索引效率就會降低。

反之,負載因子越小則鍊錶中的資料量就越稀疏,此時會對空間造成爛費,但是此時索引效率高。

如何科學設定 initailcapacity,loadfactor的值

hashmap有三個建構函式,可以選用無參建構函式,不進行設定。預設值分別是16和0.75.

官方的建議是initailcapacity設定成2的n次冪,laodfactor根據業務需求,如果迭代效能不是很重要,可以設定大一下。

為什麼initailcapacity要設定成2的n次冪,網友解釋了,我覺得很對,以下摘自網友部落格:深入理解hashmap

左邊兩組是陣列長度為16(2的4次方),右邊兩組是陣列長度為15。兩組的hashcode均為8和9,但是很明顯,當它們和1110「與」的時候,產生了相同的結果,也就是說它們會定

位到陣列中的同乙個位置上去,這就產生了碰撞,8和9會被放到同乙個鍊錶上,那麼查詢的時候就需要遍歷這個鍊錶,得到8或者9,這樣就降低了查詢的效率。同時,我們也可以

發現,當陣列長度為15的時候,hashcode的值會與14(1110)進行「與」,那麼最後一位永遠是0,而0001,0011,0101,1001,1011,0111,1101這幾個位置永遠都不能

存放元素了,空間浪費相當大,更糟的是這種情況中,陣列可以使用的位置比陣列長度小了很多,這意味著進一步增加了碰撞的機率,減慢了查詢的效率!

所以說,當陣列長度為2的n次冪的時候,不同的key算得得index相同的機率較小,那麼資料在陣列上分布就比較均勻,也就是說碰撞的機率小,相對的,查詢的時候就不用

遍歷某個位置上的鍊錶,這樣查詢效率也就較高了。

resize()方法

initailcapacity,loadfactor會影響到hashmap擴容。

hashmap每次put操作是都會檢查一遍 size(當前容量)>initailcapacity*loadfactor 是否成立。如果不成立則hashmap擴容為以前的兩倍(陣列擴成兩倍),

然後重新計算每個元素在陣列中的位置,然後再進行儲存。這是乙個十分消耗效能的操作。

所以如果能根據業務預估出hashmap的容量,應該在建立的時候指定容量,那麼可以避免resize().

HashMap 負載因子

static final float default load factor 0.75f 大概意思就是說,在理想情況下,使用隨機雜湊碼,節點出現的頻率在hash桶中遵循泊松分布,同時給出了桶中元素個數和概率的對照表。從上面的表中可以看到當桶中元素到達8個的時候,概率已經變得非常小,也就是說用0.75...

HashMap容量和負載因子

引自 hashmap底層資料結構是陣列 鍊錶,jdk1.8中還引入了紅黑樹,當鍊表長度超過8個時,會將鍊錶轉成紅黑樹,以提公升其查詢效能。那麼,給出乙個節點,hashmap是如何確定這個節點應該放在具體哪個位置呢?以jdk1.8為例 final v putval int hash,k key,v v...

HashMap的負載因子為何預設是0 75

hashmap負載因子,與擴容機制有關 即若當前容器的容量,達到設定最大值,就需要要執行擴容操作。舉個例子 當前的容器容量是16,負載因子是0.75 16 0.75 12,也就是說,當容量達到了12的時就會執行擴容操作。作用很簡單,相當於是乙個擴容機制的閾值。當超過了這個閾值,就會觸發擴容機制。ha...