HashMap的負載因子為什麼不設定成1

2021-10-03 17:15:50 字數 2161 閱讀 5680

為什麼hashmap的負載因子設定成0.75,而不是1也不是0.5?這背後到底有什麼考慮?

在hashmap原始碼中 hashmap預設容量大小是16,最大容量是2的30次方,預設的負載因子是0.75f;

static final int default_initial_capacity = 1 << 4; // aka 16

static final int maximum_capacity = 1 << 30;

static final float default_load_factor = 0.75f;

負載因子(loadfactor)表示hashmap滿的程度,預設值為0.75f,也就是說預設情況下,當hashmap中元素個數達到了容量的3/4的時候就會進行自動擴容。

第一次建立hashmap的時候,就會指定其容量(如果未明確指定,預設是16)。隨著我們不斷的向hashmap中put元素的時候,就有可能會超過一定的閾值,那麼就需要有乙個擴容機制。所謂擴容,就是擴大hashmap的容量(jdk1.8):

final v putval(int hash, k key, v value, boolean onlyifabsent,

boolean evict)

從**中我們可以看到,在向hashmap中新增元素過程中,如果元素個數(size)超過臨界值(threshold)的時候,就會進行自動擴容(resize),並且,在擴容之後,還需要對hashmap中原有元素進行rehash,即將原來桶中的元素重新分配到新的桶中。

在hashmap中,臨界值(threshold) = 負載因子(loadfactor) * 容量(capacity)。

hashmap在擴容到過程中不僅要對其容量進行擴充,還需要進行rehash!所以,這個過程其實是很耗時的,並且map中元素越多越耗時。rehash的過程相當於對其中所有的元素重新做一遍hash,重新計算要分配到那個桶中。

hashmap 是乙個陣列加鍊表的結構,不擴容也是可以無限儲存的,為什麼要擴容?

擴容是為解決雜湊衝突問題。hashmap其實是底層基於雜湊函式實現的,但是雜湊函式都有如下乙個基本特性:根據同一雜湊函式計算出的雜湊值如果不同,那麼輸入值肯定也不同。但是,根據同一雜湊函式計算出的雜湊值如果相同,輸入值不一定相同。兩個不同的輸入值,根據同一雜湊函式計算出的雜湊值相同的現象叫做碰撞。

hashmap將陣列和鍊錶(或者紅黑樹)組合在一起,發揮了兩者的優勢,我們可以將其理解為鍊錶的陣列。但是,如果乙個hashmap中衝突太高,那麼陣列的鍊錶就會退化為鍊錶。這時候查詢速度會大大降低。

為了解決雜湊衝突問題,在合適的時候擴大陣列容量,再通過乙個合適的hash演算法計算元素分配到哪個陣列中,就可以大大的減少衝突的概率。就能避免查詢效率低下的問題。

為了避免雜湊碰撞,hashmap需要在合適的時候進行擴容。那就是當其中的元素個數達到臨界值的時候,而這個臨界值前面說過和loadfactor有關,換句話說,設定乙個合理的loadfactor,可以有效的避免雜湊衝突。

關於loadfactor在jdk官方文件裡有說明:一般來說,預設的負載因子(0.75)在時間和空間成本之間提供了很好的權衡。更高的值減少了空間開銷,但增加了查詢成本(反映在hashmap類的大多數操作中,包括get和put)。

試想一下,如果我們把負載因子設定成1,容量使用預設初始值16,那麼表示乙個hashmap需要在"滿了"之後才會進行擴容。那麼在hashmap中,最好的情況是這16個元素通過hash演算法之後分別落到了16個不同的桶中,否則就必然發生雜湊碰撞。而且隨著元素越多,雜湊碰撞的概率越大,查詢速度也會越低。

如果負載因子設定為0.5,那麼就會頻繁的擴容,浪費空間。

loadfactor=0.75科學依據

a .根據數學公式推算。負載因子為log(2)的時候,可以既減少雜湊衝突,又浪費空間,是時間和空間的權衡。

log(2)大約為0.7。

b.根據hashmap的擴容機制,應該保證capacity的值永遠都是2的冪。

為了保證負載因子(loadfactor) * 容量(capacity)的結果是乙個整數,這個值是0.75(3/4)比較合理,因為這個數和任何2的冪乘積結果都是整數。

參考:

HashMap 負載因子

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

HashMap的負載因子

下面是hashmap的乙個建構函式,兩個引數initialcapacity,loadfactor 這關係hashmap的迭代效能。constructs an empty hashmap with the specified initial capacity and load factor.param...

為什麼hashMap的比例因子要0 75?

最近在看hashmap原始碼,對於擴容因子 0.75感到很費解,為什麼在用了75 的容量的時候就要進行擴容呢?陣列中明明還有25 的空間沒有使用。為什麼不等到陣列幾乎滿了 擴容因子 0.95 的時候才進行擴容?擴容因子 0.95和擴容因子 0.75有什麼區別嗎?首先來看一下什麼是擴容因子。假設has...