HashMap 原始碼分析

2021-10-06 02:19:14 字數 3451 閱讀 3336

public

static

void

main

(string[

] args)

1、建立 hashmap,使用的是無參構造器

static

final

float default_load_factor =

0.75f

;final

float loadfactor;

public

hashmap()

2、新增 k,v 鍵值對(首次新增步驟為:1.x.x… ,後續新增步驟為:2.x.x…)

public v put

(k key, v value)

// 處理 key 的 hash 值

static

final

inthash

(object key)

// 用於儲存 map 資料的單元,一組資料就是乙個 node,也就是乙個 entry

static

class

node

implements

map.entry

public

final k getkey()

public

final v getvalue()

public

final string tostring()

public

final

inthashcode()

public

final v setvalue

(v newvalue)

public

final

boolean

equals

(object o)

return

false;}

}

transient node

table;

// 首次新增元素 table 是預設初始化 null;後續新增,為當前容量的 node 陣列

int threshold;

// 首次新增元素 threshold 為預設初始化 0;後續新增為:容量 * 0.75

static

final

int default_initial_capacity =

1<<4;

// 預設初始化容量:16

static

final

float default_load_factor =

0.75f

;// 預設裝載因子:0.75

transient

int size;

// map 中儲存的資料數量

static

final

int treeify_threshold =8;

// 當鍊表深度大於 8 時轉換為二叉樹

// 初始化/重新設定容量,擴容的步驟使用(kr - 數字)編號,以首次擴容為例

final node

resize()

// 此時新容量為舊容量的 2 倍,即 newcap = 32

elseif(

(newcap = oldcap <<1)

< maximum_capacity &&

oldcap >= default_initial_capacity)

// 新閾值為舊閾值的 2 倍,即 oldcap = 24

newthr = oldthr <<1;

}else

if(oldthr >0)

newcap = oldthr;

// 1.1.1 - 4 首次新增:oldcap = 0,oldthr = 0,所以進入 else,對容量和閾值進行初始化

else

if(newthr ==0)

// 1.1.1 - 5 將 threshold 賦值為 newthr = 12

// kr - 5 將 threshold 賦值為 newthr = 24

threshold = newthr;

@suppresswarnings()

// 1.1.1 - 6 建立乙個 newtab 的 node 陣列,初始化容量為:newcap = 16

// kr - 6 按照新容量 newcap = 32 建立乙個 node 陣列 newtab

node

newtab =

(node

)new

node

[newcap]

;// 1.1.1 - 7 將 newtab 賦值給 table

// kr - 7 將 newtab 賦值給 table

table = newtab;

// kr - 8 將舊表中的資料按照(e.hash & (newcap - 1))規則複製到新錶中

if(oldtab != null)

else

}while

((e = next)

!= null);if

(lotail != null)

if(hitail != null)}}

}}// 1.1.1 - 8 將初始化容量為 16 後的 node 陣列返回

return newtab;

}node

newnode

(int hash, k key, v value, node

next)

// 新增元素到 map 結構中的具體操作

final v putval

(int hash, k key, v value,

boolean onlyifabsent,

boolean evict)

// 若以存在節點的下乙個節點(e)不為空,判斷該節點和當前需要儲存的元素 hash 和 key 是否

// 相等

if(e.hash == hash &&

((k = e.key)

== key ||

(key != null && key.

equals

(k))))

break

; p = e;}}

// 將相同 key 的元素,舊值替換為新值,並將舊值返回

if(e != null)

}++modcount;

// 對當前資料量 +1,並與 threshold(閾值:12)比較,若大於該值,進行擴容if(

++size > threshold)

// 若大於了閾值,要進行擴容

resize()

;afternodeinsertion

(evict)

;return null;

}

HashMap原始碼分析

public hashmap int initialcapacity,float loadfactor 2 接下來是重要的put方法,put方法用於將鍵值對儲存到map中,讓我們來具體分析一下。public v put k key,v value if key null 若key為null,則將va...

HashMap 原始碼分析

1 getentry object key 方法 final entrygetentry object key return null 根據key的hash值計算出索引,得到table中的位置,然後遍歷table處的鍊錶 for entrye table indexfor hash,table.le...

HashMap原始碼分析

public v put k key,v value if key null return putfornullkey value int hash hash key int i indexfor hash,table.length for entrye table i e null e e.nex...