⭐ 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;
}
⭐ gettreenodefinal 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...