HashMap之put方法原始碼理解總結

2021-09-11 23:37:51 字數 2769 閱讀 1591

引入

在理解hashmap的put方法之前,需要對hashmap有一些基礎的理解。

1.hashmap的資料結構:陣列 + 鍊錶 + 紅黑樹

2.put資料的大概流程

1.首次put資料

當定義了乙個hashmap結構,在第一次呼叫put方法進行,新增資料的時候,首先會對hashmap結構進行初始化,生成長度為16的陣列。

然後插入的資料呼叫hash(key)生成hash值,用來定位資料在陣列中的位置,若之後再次插入資料的位置與之前相同則使用鍊錶的結構,繼續向下插入,直到鍊錶長度等於8,將鍊錶轉化為紅黑樹。

//陣列的預設大小。

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;

//鍊錶的上限個數

static final int treeify_threshold = 8;

//紅黑樹節點個數小於6轉化為鍊錶

static final int untreeify_threshold = 6;

//轉換紅黑樹的最小節點數,小於64不會轉化紅黑樹,而是選擇擴容

static final int min_treeify_capacity = 64;

static class nodeimplements map.entry

...}

//表示整個hashmap資料結構

transient node table;

//記錄陣列使用格仔的情況

transient int size;

//當前陣列容量*擴容因子:表示擴容元素個數臨界值

int threshold;

public v put(k key, v value)
static final int hash(object key)
final v putval(int hash, k key, v value, boolean onlyifabsent,

boolean evict)

//進入迴圈時,就將p.next的值賦給了e,如果key值相同,直接跳出迴圈,判斷e值進行插入即可

if (e.hash == hash &&

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

break;

//p = e;}}

//如果e值不為空,代表時相同的key值進行的value值替換,此時返回被替換掉的值

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

//size為當前節點的個數,threshold為擴容的閾值

//如果當前的節點數大於閾值將呼叫resize()擴容(每次以兩倍陣列大小進行擴容)

if (++size > threshold)

resize();

afternodeinsertion(evict);

return null;

}

//對陣列進行初始化操作,以及擴容操作

final node resize()

//如果沒有超過最大值,使用位移操作進行雙倍擴容

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

oldcap >= default_initial_capacity)

newthr = oldthr << 1; // double threshold

}else if (oldthr > 0) // initial capacity was placed in threshold

newcap = oldthr;

//第乙個初始化,定義了乙個陣列的預設大小變數,乙個擴容一次大小的變數

else

if (newthr == 0)

//threshold

threshold = newthr;

//第一次put建立初始化的陣列,沒次擴容形成的新的陣列

@suppresswarnings()

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

table = newtab;

//重新雜湊的過程:分為三種情況(空,鍊錶,紅黑樹)

if (oldtab != null)

else

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

//為0在原來位置不動

if (lotail != null)

//不為0在原來位置加上原容量的位置

if (hitail != null) }}

}}

return newtab;

}

HashMap的Put方法(二)

hashmap類中有如下put方法 方法體省略 public v put k key,v value final v putval int hash,k key,v value,boolean onlyifabsent,boolean evict public void putall map ext...

HashMap原始碼之get與put方法

hashmap是基於陣列和鍊錶來儲存鍵值對物件的,我們簡單看下get和put方法的原始碼。1 我們呼叫put方法來儲存鍵值對時,它先呼叫hash方法來計算hashcode,然後用hashcode和entry陣列的大小來做按位與操作,求出所在的entry陣列的下標位置。通過key與下標所在的entry...

HashMap 的 get 方法的流程分析(原始碼)

流程首先根據 hash 方法獲取到 key 的 hash 值 然後通過 hash length 1 的方式獲取到 key 所對應的node陣列下標 length對應陣列長度 首先判斷此結點是否為空,是否就是要找的值,是則返回空,否則進入第二個結點。接著判斷第二個結點是否為空,是則返回空,不是則判斷此...