HashMap 原始碼重識

2021-10-20 07:36:18 字數 3199 閱讀 2211

⭐ hashmap 重要的變數

// 預設的初始容量

static final int default_initial_capacity = 1 << 4; // aka 16

// 最大的容量,且必須是2的倍數

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;

//可將其分類為樹木的最小桌子容量。(否則,如果bin中的節點過多,則將調整表的大小。)

//至少應為4 * treeify_threshold,以避免衝突在調整大小和樹化閾值之間。

static final int min_treeify_capacity = 64;

//該錶在首次使用時初始化,並根據需要調整大小。 分配時,長度始終是2的冪。 (在某些操作中,我們還允許長度為零,以允許使用當前不需要的引導機制。)

transient node table;

// map 內元素的size

transient int size;

⭐ 構造方法
// 預設負載因子為 0.75 初始化容量是 16   

public hashmap()

// 指定初始化容量 以及負載因子

public hashmap(int initialcapacity, float loadfactor)

// 對於給定的目標容量,返回兩倍大小的冪。

static final int tablesizefor(int cap)

public hashmap(int initialcapacity)

⭐ put 方法

mapmap = new hashmap<>(17);

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

boolean evict)

// key已經存在直接覆蓋value

if (e.hash == hash &&

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

break;

p = e;}}

// 當key重複,直接替換value 並返回原來的value

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

// 這裡將 size 進行 ++ ,並判斷與threshold的關係,進行tab的闊容

// 例如 : 17 > 32 > 32 * 0.75 > 24

// 這裡大概的意思就是,我們在構造方法傳入 17 ,但是經過計算 threshold =32 ,經過resize 後24

if (++size > threshold)

resize();

afternodeinsertion(evict);

return null;

}

⭐ resize()方法
final node resize() 

//沒超過最大值,就擴充為原來的2倍

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;

// 計算新的resize上限

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)

// 原索引+oldcap放到bucket裡

if (hitail != null) }}

}}

return newtab;

}

⭐ treeifybin()方法

final void treeifybin(node tab, int hash) 

tl = p;

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

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

//形成具體的樹

hd.treeify(tab);

}}

public v get(object key) 

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

return null;

}

⭐ gettreenode
final treenodegettreenode(int h, object k) 

//使用給定的雜湊和金鑰查詢從根p開始的節點。

final treenodefind(int h, object k, class<?> kc) while (p != null);

return null;

}

今天的分享就到這裡,不足之處還請大家多多指教

HashMap原始碼系列 HashMap的屬性

public class hashmap extends abstractmap implements map,cloneable,serializable容載因子 容載因子越大,table陣列中儲存的資料越密集,碰撞的可能性就越大。容載因子越小,儲存越稀疏,碰撞的可能性就越小,不過浪費儲存空間。轉...

HashMap原始碼解讀

一 建立乙個hashmap都做了哪些工作?mapmap new hashmap hahmap無參構造方法 public hashmap 可以看到設定了載入因子 預設0.75 閾值 預設容量16 預設載入因子0.75 12 table是hashmap內部資料儲存結構entry陣列。當hashmap的s...

HashMap原始碼分析

public hashmap int initialcapacity,float loadfactor 2 接下來是重要的put方法,put方法用於將鍵值對儲存到map中,讓我們來具體分析一下。public v put k key,v value if key null 若key為null,則將va...