引入
在理解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對應陣列長度 首先判斷此結點是否為空,是否就是要找的值,是則返回空,否則進入第二個結點。接著判斷第二個結點是否為空,是則返回空,不是則判斷此...