JDK1 8 HashMap原始碼解析

2021-10-01 09:24:42 字數 3478 閱讀 2566

普通常量

//儲存node鍊錶的陣列

transient node

table;

//由node節點構成的set集合

transient set

> entryset;

//hashmap儲存元素的數量

transient

int size;

//記錄hashmap結構性變化的次數(value覆蓋不算)和fail-fast機制有關

transient

int modcount;

//threshold的值應等於 table.length * loadfactor, size 超過這個值時進行 resize()擴容

int threshold;

//hashmap裝載因子

final

float loadfactor;

靜態常量

//預設的初始化容器容量16,並且官網上說必須是2的次冪

static

final

int default_initial_capacity =

1<<4;

// aka 16

//容器最大容量2的30次冪

static

final

int maximum_capacity =

1<<30;

//容器的裝載因子,無參構造函式呼叫

static

final

float default_load_factor =

0.75f

;//確定鍊錶轉為紅黑樹的臨界值

static

final

int treeify_threshold =8;

//確定紅黑樹轉為鍊錶的臨界值

static

final

int untreeify_threshold =6;

//陣列元素容量,如果陣列元素小於該值,不會轉為紅黑樹

static

final

int min_treeify_capacity =

64;

建構函式

//初始化預設裝載因子

public

hashmap()

//初始化指定的容量

public

hashmap

(int initialcapacity)

//初始化指定的容量和裝載因子

public

hashmap

(int initialcapacity,

float loadfactor)

public

hashmap

(map<

?extendsk,

?extends

v> m)

一些重要的方法

至於putval方法,可以看hashmap的put原始碼分析

public v put

(k key, v value)

puall方法

public

void

putall

(map<

?extendsk,

?extends

v> m)

/*若 evict 為 false,代表是在建立 hashmap 時呼叫了這個函式,

例如利用上述建構函式public hashmap(map<? extends k, ? extends v> m)建立 hashmap;

若 evict 為true,代表是在建立 hashmap 後才呼叫這個函式,例如上述的 putall 函式

evict為true也呼叫afternodeinsertion方法,刪除頭結點有關

*/final

void

putmapentries

(map<

?extendsk,

?extends

v> m,

boolean evict)

//table不為null,如果插入的map容量大於臨界值threshold,則進行擴容

else

if(s > threshold)

resize()

;for

(map.entry<

?extendsk,

?extends

v> e : m.

entryset()

)}}/*

高低十六位

主要是從速度、功效、質量來考慮的,這麼做可以在陣列table的length比較小的時候,也能保證考慮到高低bit都參與到hash的計算中,同時不會有太大的開銷

*/static

final

inthash

(object key)

tablesizefor方法和integer方法類似

其實開始的部分 右移以及異或的目的在於讓i的每一位都為1

比如i為10

0000 1010

0000 0101 >>>1

0000 1010 |

0000 1111 結果

對於tablesizefor方法,是將n+1 那麼就會進製,比如上面的例子 10得到1111 +1之後得到

0001 0000 即16

對於highestonebit方法是 i - (i >>>1),當i右移一位後發現最高位為0其餘為均為1,i再減去則會使得最高位為1其餘為為0,如上面的例子 右移一位得到 0000 0111 則

0000 1111 i

0000 0111 i >>>1

減去得 1000

/*

返回比cap大的最小的2的次冪數

比如cap return值

3 4

9 16

37 64

259 512

......

* */

static

final

inttablesizefor

(int cap)

得到比i小的2的次冪

/*i return

5 4

9 8

45 32

67 64

*/使用

public

static

inthighestonebit

(int i)

get方法

public v get

(object key)

final node

getnode

(int hash, object key)

while

((e = e.next)

!= null);}

}return null;

}

JDK 1 8 HashMap原始碼解析

put方法分析 public v put k key,v value hash方法解析 減少hash衝突 static final int hash object key putval方法具體實現 final v putval int hash,k key,v value,boolean onlyi...

JDK1 8 HashMap原始碼解析

static final int default initial capacity 1 4 static final int maximum capacity 1 30 static final float default load factor 0.75f 當hashmap的容量增加到當前容量的3...

JDK 1 8 HashMap擴容原理

擴容前計算索引 1010 0101 0000 1111 0000 0101 索引結果 5擴容以後容量是n 32 對應的二進位制是0001 1111 node本身的hash值是不變的,仍然是1010 0101,那麼擴容後node 的索引的計算是通過如下方式得到 擴容後計算索引 1010 0101 00...