HashMap原始碼解析

2021-09-11 10:55:56 字數 2182 閱讀 3859

預設字段:

static final int default_initial_capacity = 1 << 4; //預設node的陣列長度 16

static final int maximum_capacity = 1 << 30; //陣列的最大長度 2^30

static final float default_load_factor = 0.75f; //負載因子 擴容的閥值 = 陣列長度 * 負載因子

static final int treeify_threshold = 8; //鍊錶變為紅黑樹的長度 即樹化的長度

static final int untreeify_threshold = 6; //紅黑樹變為鍊錶的大小

public v put(k key, v value) 

/*** hash:key的雜湊值

* key:要存入的key

* value:要存入的value

* onlyifabsent:為true 不覆蓋已經存在的鍵的值

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

boolean evict)

//如果e和key的值相等 就退出迴圈

if (e.hash == hash &&

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

//從這塊退出的時候e指向的是map中已經存在的key節點

break;

//e指向的是p的後驅元素

p = e;}}

//如果e不為空 說明當前的key已經存在了map當中 返回key對應的舊的value

//遵循相同的鍵值覆蓋

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

//e的值設為value

e.value = value;

afternodeaccess(e);

//返回舊的值

return oldvalue;}}

//map在結構上面被改變的次數 如put、del方法都會使這個值加一

++modcount;

//如果元素個數大於閥值的話 map進行擴容

//疑問點: hash擴容應該是陣列中的元素個數。。。。

if (++size > threshold)

resize();

afternodeinsertion(evict);

return null;

}

final node resize() 

//原有陣列乘2小於陣列最大容量(2的30次方) 並且大於等於預設的陣列長度的大小(16)擴容的閥值乘以2

else if ((newcap = oldcap << 1) < maximum_capacity &&

oldcap >= default_initial_capacity)

newthr = oldthr << 1; // double threshold

} else if (oldthr > 0) // 初始容量設定為閾值(老陣列的長度不大於0 並且它的閥值大於0)

newcap = oldthr;

else

if (newthr == 0)

//經過上面一系列的操作 找到新的擴容的閥值 正式進行擴容

threshold = newthr;

@suppresswarnings()

//建立新的node陣列、長度為上述一系列操作後確認的值(一般為老的陣列長度的兩倍)

node newtab = (node) new node[newcap];

table = newtab;

if (oldtab != null) else

} while ((e = next) != null);

//當前索引的尾節點不為空

if (lotail != null)

//當前位置+原來陣列長度位置的尾節點不為空

if (hitail != null) }}

}}

return newtab;

}

HashMap原始碼解析

以jdk1.8為例,hashmap是乙個用於儲存key value鍵值對的集合,每乙個鍵值對是乙個node jdk1.7叫做entry 後台是用乙個node陣列來存放資料,這個node陣列就是hashmap的主幹。這裡我們主要來分析hashmap的get和put方法。public v put k k...

hashMap 原始碼解析

這幾天跳槽 被人問得最多的問題就是基礎方面的知識.當時學習的時候有點囫圇吞棗.現在回頭把這些基本的集合類原始碼都仔細閱讀下 hashmap 用的是最頻繁的.所以問得也最多了.initcapacity 初始化的容量 loadfacotr 負載因子 主要用來計算threshold的值 threshold...

Hashmap原始碼解析

話不多說,直接看hashmap的put 方法原始碼 這是jdk1.8的原始碼 與1.7有所不同。final v putval int hash,k key,v value,boolean onlyifabsent,boolean evict if e.hash hash k e.key key ke...