HashMap原理底層剖析
resize 函式
// 將集合擴容
final Node<K,V>[] resize() {
Node<K,V>[] oldTab = table;
// 舊錶的容量
int oldCap = (oldTab == null) ? 0 : oldTab.length;
// 之前的閾值
int oldThr = threshold;
int newCap, newThr = 0;
// 這裡也可以說集合不為空
if (oldCap > 0) {
if (oldCap >= MAXIMUM_CAPACITY) {// 如果集合現在陣列的長度大於等於最大容量
threshold = Integer.MAX_VALUE;// 將整型最大的值賦值給 threshold
return oldTab;
}
// 當前集合陣列長度擴大二倍賦值給 newCap 小於 MAXIMUM_CAPACITY
// 並且集合的容量大於等於預設容量將當前閾值擴大二倍賦值給新的閾值
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
// 若沒有經歷過初始化,透過建構函式指定了 initialCapcity ,將當前容量設定為大於它最小的 2 的 n 次方
else if (oldThr > 0)
newCap = oldThr;
else { // 初始的時候長度和閾值都使用預設值
newCap = DEFAULT_INITIAL_CAPACITY;
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
}
// 重新計算 threshold
if (newThr == 0) {
float ft = (float)newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
(int)ft : Integer.MAX_VALUE);
}
// 更新當前集合閾值
threshold = newThr;
// 從這裡開始便是將 oldTab 資料重新 hash 放入擴容後的 newTab
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
// 將 table 指向的 oldTab 指向 newTab
table = newTab;
if (oldTab != null) {
// 遍歷雜湊表
for (int j = 0; j < oldCap; ++j) {
Node<K,V> e;
// 當前連結串列是否為 null 、並且將就連結串列賦值給 e
if ((e = oldTab[j]) != null) {
oldTab[j] = null;//外匯跟單gendan5.com 將原來位置的連結串列置為 null 方便垃圾回收
if (e.next == null)// 連結串列的長度為 1 直接將連結串列中的一個節點重新 hash 存放到相應的位置
newTab[e.hash & (newCap - 1)] = e;
else if (e instanceof TreeNode) // 表示節點型別為樹形結構
((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
else { // 連結串列是非樹形結構,並且節點數量是大於 1
// 將連結串列拆分為兩個子連結串列
Node<K,V> loHead = null, loTail = null;
Node<K,V> hiHead = null, hiTail = null;
Node<K,V> next;
do { // 透過 do...while 遍歷連結串列
next = e.next;
if ((e.hash & oldCap) == 0) {
if (loTail == null) // 設定頭節點
loHead = e;
else // 設定尾結點
loTail.next = e;
loTail = e;// 將尾結點變為最後一個節點
}
else {
if (hiTail == null)// 同上都是設定頭節點下面也一樣是設定尾結點
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
} while ((e = next) != null);
if (loTail != null) {// 在新表的 j 位置存放連結串列
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {// 在新表的 j+oldCap 位置存放連結串列
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2771210/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- HashMap的底層原理HashMap
- HashMap底層實現原理HashMap
- HashMap的底層原理分析HashMap
- HashMap原理詳解,包括底層原理HashMap
- 深度解析HashMap集合底層原理HashMap
- 深度剖析Spring Cloud底層原理SpringCloud
- 漫畫:什麼是HashMap?(底層原理)HashMap
- HashMap原理(一) 概念和底層架構HashMap架構
- 最通俗易懂搞定HashMap的底層原理HashMap
- [java]HashMap原理剖析JavaHashMap
- ArrayList 從原始碼角度剖析底層原理原始碼
- HashMap底層實現原理/HashMap與HashTable區別/HashMap與HashSet區別HashMap
- Java進階:HashMap底層原理(通俗易懂篇)JavaHashMap
- 面試必問:HashMap 底層實現原理分析面試HashMap
- HashMap的底層結構、原理、擴容機制HashMap
- HashMap的實現原理 HashMap底層實現,hashCode如何對應bucket?HashMap
- Redis List 底層三種資料結構原理剖析Redis資料結構
- OC底層探索(十六) KVO底層原理
- synchronized底層原理synchronized
- ConcurrentHashMap底層原理HashMap
- 十分鐘快速掌握HashMap底層實現原理(圖文詳解)HashMap
- 深度解析HashMap底層實現架構HashMap架構
- Java阻塞佇列中的異類,SynchronousQueue底層實現原理剖析Java佇列
- Volatile的底層原理
- golang select底層原理Golang
- ArrayList集合底層原理
- RabbitMq底層原理分析MQ
- Spring Cloud底層原理SpringCloud
- RunLoop底層原理探究OOP
- Netty的底層原理Netty
- iOS底層原理-CategoryiOSGo
- Mysql鎖機制與最佳化實踐以及MVCC底層原理剖析MySqlMVC
- HashMap底層資料結構原始碼解析HashMap資料結構原始碼
- InnoDB索引與底層原理索引
- AOP底層原理之CGlibCGLib
- 理解PHP底層原理(一)PHP
- 初步理解 JavaScript 底層原理JavaScript
- volatile底層原理詳解