HashMap的底層實現原理

2022-05-22 13:21:06 字數 3137 閱讀 1737

hashmap map = new hashmap();

在例項化以後,底層建立了長度是16的一維陣列entry table(陣列的型別為entry,陣列名稱為table)。

...可能已經執行過多次put操作...

map.put(key1,value1):

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

1. 如果此位置上的資料為空,此時的key1-value1新增成功。

2.如果此位置上的資料不為空,(意味著此位置上存在乙個或多個資料(以鍊錶形式存在)),比較key1和已經存在的乙個或多個資料的雜湊值:

2.1如果key1的雜湊值與已經存在的資料的雜湊值都不相同,此時key1-value1新增成功。----此時key1-value1和原來的資料以鍊錶的方式儲存。

2.2如果key1的雜湊值和已經存在的某乙個資料(key2-value2)的雜湊值相同,繼續比較:呼叫key1所在類的equals(key2)方法,進行比較:

2.2.1如果equals()返回false:此時key1-value1新增成功。----此時key1-value1和原來的資料以鍊錶的方式儲存。

2.2.2如果equals()返回true:使用value1替換value2。想當於此時的put方法具有修改功能。

在不斷的新增過程中,會涉及到擴容問題,當超出臨界值(且要存放的位置非空)時,擴容。預設的擴容方式:擴容為原來容量的2倍,並將原有的資料複製過來。

1. new hashmap():底層沒有在剛開始就建立乙個長度為16的陣列。

2. jdk 1.8底層建立的陣列是:node型別的node,而非entry。

3. 在首次呼叫put()方法時,底層才會建立長度為16的陣列。

4. jdk 1.7底層結構只有:陣列+鍊錶。jdk8中底層結構:陣列+鍊錶+紅黑樹。

4.1 形成鍊錶時,七上八下(jdk 1.7:新的元素指向舊的元素。jdk 1.8:舊的元素指向新的元素)。

4.2 當陣列的某乙個索引位置上的元素以鍊錶形式存在的資料個數 > 8 且當前陣列的長度 > 64時,

此時此索引位置上的資料改為使用紅黑樹儲存,提高了查詢元素的速度。

default_initial_capacity : hashmap的預設容量:    16

default_load_factor:hashmap的預設載入因子:  0.75

threshold:擴容的臨界值,= 容量 * 填充因子: 16 * 0.75  --->   12

treeify_threshold:bucket中煉表長度大於該預設值,轉化為紅黑樹  :  8

min_treeify_capacity:桶中的node被樹化時最小的hash表容量  :  64

public class hashmapextends abstractmapimplements map, cloneable, serializable 

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;}}

public hashmap()

public hashmap(map<? extends k, ? extends v> m)

public v put(k key, v value)

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;

}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 = newthr;

@suppresswarnings()

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

table = newtab;

if (oldtab != null)

else

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

if (lotail != null)

if (hitail != null) }}

}}

return newtab;

}final void treeifybin(node tab, int hash)

tl = p;

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

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

hd.treeify(tab);

}}

hashmap底層實現原理

每次初始化hashmap都會構造乙個table陣列,而table陣列的元素為entry節點。static class entryimplements map.entryhashmap也可以說是乙個陣列鍊錶,hashmap裡面有乙個非常重要的內部靜態類 entry,這個entry非常重要,它裡面包含了...

HashMap底層實現原理

hashmap map new hashmap 在例項化以後,底層建立了長度為16的一維陣列entry table 已經執行過put操作.map.put key1 value1 呼叫key1所在類的hashcode 計算key1雜湊值,此雜湊值經過某種演算法計算後,得到在entry陣列中的存放位置 ...

HashMap底層實現原理

一 jdk1.7中hashmap的底層實現原理 首先,當我們通過hashmap的構造方法建立乙個hashmap物件時,底層就會建立乙個entry型別的一維陣列 預設初始化長度為16 當我們執行put操作的時候,會呼叫key所屬類的hashcode方法計算出key的hash值,然後將hash值通過雜湊...