容器 HashMap的原始碼分析(JDK1 8)

2021-10-24 02:07:50 字數 2853 閱讀 8573

public class maptest 

}

//無參構造,設定負載係數為預設值

public hashmap()

//負載係數預設值為0.75f

static final float default_load_factor = 0.75f;

public v put(k key, v value) 

/*1.對key執行雜湊演算法*/

static final int hash(object key)

/*2.執行新增操作*/

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

boolean evict)

if (e.hash == hash &&

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

break;

p = e;}}

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

if (++size > threshold)

resize();

afternodeinsertion(evict);

return null;

} static class nodeimplements map.entry

public final k getkey()

public final v getvalue()

public final string tostring()

public final int hashcode()

public final v setvalue(v newvalue)

public final boolean equals(object o)

return false;}}

//預先定義的空的node

transient hashmap.node table;

//大意就是,第一次新增時按預設容量大小(16)建立node,負載達到預設的負載率,然後按照2倍擴容

final hashmap.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

//正常不會出現這種情況,有的話應該是位移計算導致的0,此時超過了int的範圍

if (newthr == 0)

threshold = newthr;

@suppresswarnings()

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

table = newtab;

if (oldtab != null)

else

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

if (lotail != null)

if (hitail != null) }}

}}

return newtab;

}/*轉換紅黑樹(陣列某位置的元素,鍊錶長度大於8個,即下標大於7,treeify_threshold=8,且陣列長度大於min_treeify_capacity=64)*/

final void treeifybin(hashmap.node tab, int hash)

tl = p;

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

if ((tab[index] = hd) != null)

hd.treeify(tab);

}}

3.1首先,呼叫key1所在類的hashcode()計算key1雜湊值,此雜湊值經過某種演算法計算以後,得到在node陣列中的存放位置。

3.2如果此位置上的資料為空,直接新增 ——情況1

3.3如果此位置的資料不為空,並且不是紅黑樹和鍊錶,就比較進行替換或者新增,形成鍊錶——情況2

3.4如果此位置上的資料不為空,並且是紅黑樹,就挨個比較進行替換或者新增——情況3

3.5如果此位置上的資料不為空,並且是鍊錶,挨個比較,替換或者——情況4

3.6不滿足替換條件時,且不滿足生成紅黑樹的條件,那就繼續使用鍊錶儲存——情況5

3.7不滿足替換條件時,且滿足生成紅黑樹的條件,那就將鍊錶改為紅黑樹儲存——情況64.1 在不斷的新增過程中,會涉及到擴容問題,當超出臨界值(且要存放的位置非空)時,擴容。預設的擴容方式:擴容為原來容量的2倍,並將原有的資料複製過來。

4.2 jdk7底層結構只有:陣列+鍊錶。jdk8中底層結構:陣列+鍊錶+紅黑樹。

4.3 形成鍊錶時,七上八下(jdk7:新的元素指向舊的元素。jdk8:舊的元素指向新的元素)

4.4 當陣列的某乙個索引位置上的元素以鍊錶形式存在的資料個數 > 8 且當前陣列的長度 > 64時(不到64時,直接擴容,不是用紅黑樹),此時此索引位置上的所資料改為使用紅黑樹儲存。

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...