HashMap原始碼原理

2022-07-31 03:57:14 字數 1749 閱讀 3887

hashmap原始碼解析(負載因子,樹化策略,內部hash實現,resize策略)

內部屬性:

負載因子: final

float

loadfactor(預設為0.75f)

實際容量:

int threshold = loadfactor *tab.length;

樹化閾值:

int treeify_threshold = 8;

解除樹化閾值:

int untreeify_threshold = 6;

hashmap也採用懶載入策略,第一次put時初始化雜湊表。

樹化邏輯:索引下標對應的鍊錶長度達到閾值8並且當前雜湊表長度達到64才會樹化,否則只是呼叫resize方法進行雜湊表擴容。

resize():擴容為原先陣列的2倍
負載因子過大會導致雜湊衝突明顯增加,節省記憶體.

負載因子過小會導致雜湊表頻繁擴容,記憶體利用率低。

為何jdk1.8要引入紅黑樹?

當鍊表長度過長時,會將雜湊表查詢的時間複雜度退化為o(n)

樹化保證即便在雜湊衝突嚴重時,查詢時間複雜度也為o(logn)
當紅黑樹節點個數在擴容或刪除元素時減少為6以下,在下次resize過程中會將紅黑樹退化為鍊錶

,節省空間。

public v put(k key, v value)

hashmap內部hash

static final int hash(object key)

為何不直接使用object提供的hashcode?

將雜湊碼保留一半,將高低位都參與雜湊運算,減少記憶體開銷,減少雜湊衝突。

(h = key.hashcode()) ^ (h >>> 16)

put內部邏輯:

1.雜湊表索引下標計算:

i = (n - 1) & hash

保證求出的索引下標都在雜湊表的長度範圍之內。

2.n : 雜湊表長度

n必須為2^n,保證雜湊表中的所有索引下標都會被訪問到。

若n=15,則以下位置永不可能儲存元素

0011

0101

1001

1011

1101

1111

15:0000 1111

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

boolean evict)

if (e.hash == hash &&

((k = e.key) == key || (key != null && key.equals(k))))

break;

p = e;}}

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

// 此時新增了新節點

if (++size > threshold)

// 擴容

resize();

afternodeinsertion(evict);

return null;

}

HashMap原理 原始碼解析

一 前言 hashmap是map實現中最常使用的,具有快速訪問的優點,所以很有必要深入到原始碼去了解其實現原理。方法 的原始碼分析。二 hashmap的資料結構 hashmap 可以理解為由陣列和鍊錶組成的儲存結構,如圖 軸方向上是乙個陣列,y方向是鍊錶。乙個節點的資訊包括 hash key val...

HashMap底層實現原理 原始碼

基於雜湊表的 map 介面的實現。此實現提供所有可選的對映操作,並允許使用null值 和 null鍵 檢視構造方法 預設初始的容量為16 arraylist預設初始值是 10 預設載入因子為0.75,什麼意思呢?就是說當資料元素達到容量的75 時,就會進行擴容 方法和map中的方法是一樣的 預設初始...

HashMap實現原理,原始碼分析

一 原始碼分析 定義陣列的初始容量。static final int default initial capacity 1 4 aka 16 定義陣列最大容量 static final int maximum capacity 1 30 定義負載因子預設值 static final float de...