HashMap JDK1 8 原始碼剖析

2021-07-23 05:02:12 字數 4773 閱讀 6451

jdk1.8相對於jdk1.6來說,區別在於1.8hashmap採用位桶+鍊錶+紅黑樹實現,

當鍊表的長度超過閾值(treeify_threshold = 8)的時候,會將鍊錶轉化為紅黑樹進行儲存。

1、hashmap的主要屬性

private

static

final

long serialversionuid = 362498820763181265l;

// 預設初始大小 aka 16

static

final

int default_initial_capacity = 1

<< 4;

//最大容量

static

final

int maximum_capacity = 1

<< 30;

//擴容比

static

final

float default_load_factor = 0.75f;

//紅黑樹閾值,當鍊表的大小大於此值是鍊錶自動轉為紅黑樹

static

final

int treeify_threshold = 8;

//紅黑樹閾值,當紅黑樹的大小小於此值是鍊錶自動轉為鍊錶

static

final

int untreeify_threshold = 6;

//樹的最小的容量,至少是 4 x treeify_threshold = 32 然後為了避免(resizing 和 treeification thresholds) 設定成64

static

final

int min_treeify_capacity = 64;

// 儲存元素的陣列,總是2的倍數

transient node table;

//快取的entryset()

transient set> entryset;

// 存放元素的個數,注意這個不等於陣列的長度。

transient

int size;

// 每次擴容和更改map結構的計數器

transient

int modcount;

// 臨界值 當實際大小(容量*填充因子)超過臨界值時,會進行擴容

int threshold;

// 填充因子

final

float loadfactor;

2、hashmap的建構函式

// 指定初始容量和填充因子的構造方法

public

hashmap(int initialcapacity, float loadfactor)

//保證初始化是2的倍數

static

final

int tablesizefor(int cap)

//指定初始容量

public

hashmap(int initialcapacity)

public

hashmap()

public

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

//初始化時可以傳入的引數可以是乙個map,會將map中的所有內容放入新的hashmap中

final

void putmapentries(map extends k, ? extends v> m, boolean evict)

else

if (s > threshold)

resize();

//將map中的所有內容放入新的hashmap中

for (map.entry extends k, ? extends v> e : m.entryset()) }}

3、主要的資料結構

資料結構為鍊錶+紅黑樹

//node是單向鍊錶,它實現了map.entry介面 

static

class

node

implements

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

//static

final

class

treenode

extends

linkedhashmap.entry

final treenoderoot()

}...//此處方法過多,需要看的可以自己去檢視原始碼

}//儲存node的陣列

transient node table;

4、put和get方法

hashmap不同於hashtable,可以key和value都可以為空

public v put(k key, v value) 

//put

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;

}public v get(object key)

//get

final nodegetnode(int hash, object key) while ((e = e.next) != null);}}

return

null;

}

5、resize方法

resize 其實是舊的node[ ]陣列複製到新擴容後的的node[ ]中

final node resize() 

else

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

oldcap >= default_initial_capacity)

//擴2倍

newthr = oldthr << 1;

}else

if (oldthr > 0)

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;

}

6、其他一些方法

//計算hash值

static

final

int hash(object key)

//取消鍊錶轉為紅黑樹

final

void treeifybin(node tab, int hash)

tl = p;

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

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

hd.treeify(tab);}}

參考客

HashMap JDK1 7原始碼分析

hashmapjdk原始碼分析 建構函式 底層資料結構 基本屬性 擴容方式 預設值繼承關係 crud方式 基本屬性 static final int default initial capacity 1 4 aka 16 雜湊表中陣列預設初始值大小為16 static final int maxim...

ArrayList原始碼分析1 8

一 arraylist屬性 1 arraylist屬性主要就是當前陣列長度size,以及存放陣列的物件elementdata陣列 public class arraylistextends abstractlistimplements list,randomaccess,cloneable,seri...

ArrayList jdk1 8原始碼分析

arraylist是執行緒非安全的陣列列表,優勢在於陣列結構,查詢效率高,修改效率較低 由下圖的類圖,可以看出arraylist是可以序列化,複製的 1 自定義初始化容量大小,int型別,值為非負數 public arraylist int initialcapacity else if initi...