resize是重新雜湊,所以要在現在容量和閾值的基礎上獲取新的容量和閾值,函式首先進行了變數定義
final hashmap.node resize()
else if ((newcap = oldcap << 1) < maximum_capacity &&
oldcap >= default_initial_capacity)//default_initial_capacity= 1<<4 = 16
newthr = oldthr << 1;
//左移一位是double,newcap和newthr都變成double
}//下面oldcap = 0,對table進行初始化,確定初始的容量和閾值
else if (oldthr > 0)
newcap = oldthr;//原來求的閾值賦值給新容量
else
if (newthr == 0)
//將 新容量*輸入的loadfactor 的值賦給新閾值,完成初始化
threshold = newthr;
確定新的table的容量和閾值之後,如果原來已儲存資料,需要對原來的資料重新雜湊,使分布均勻,這是jdk8之後對jdk7的優化,不會使鍊錶越來越長
hashmap.node newtab = (hashmap.node)new node[newcap];//產生乙個新的node陣列
table = newtab;//這一句說明只要初始化一次之後,table就不可能為0
if (oldtab != null) while ((e = next) != null);
if (lotail != null)
if (hitail != null) }}
}}
return newtab;
do···while函式就是把乙個桶對應的鍊錶上的每乙個節點,利用e.hash & oldcap的值,把原來的乙個鍊錶拆成兩個鍊錶
do
else
} while ((e = next) != null);
e.hash & oldcap 其實是取出e.hash上的乙個標誌位,因為oldcap總是2的某次方,所以oldcap用位表示是00xx10xx0的形式。
在e.hash中,oldcap中1對應的那一位,e.hash可能為0,可能為1
如果這一位是0,那麼e.hash & (oldcap-1)就等於e.hash & (newcap-1)
如果這一位是1,那麼於e.hash & (newcap-1)=e.hash & (oldcap-1)+oldcap
通過這種方法,把鍊錶上的節點分到兩個新的鍊錶中,乙個是lo鍊錶,乙個是hi鍊錶
當這個鍊錶上所有的節點都被分配完之後,再把新生成的鍊錶放進newtab的桶裡
if (lotail != null)
if (hitail != null)
使用(e.hash & oldcap) == 0來進行分配的原因:可以參考 JDk原始碼解析之四 Vector原始碼解析
具體的三個屬性 解釋看圖中注釋。vector沒有採取arraylist臨界值擴容的辦法,而是每次不夠的時候,直接根據capacity的值來增加。具體怎麼增加後面會說。vector的構造方法如下。簡單粗暴,如果呼叫無參建構函式,直接就將初始容量設定成了10,最終在右側的構造方法裡,將陣列的長度設定為1...
JDK 原始碼 閱讀
to be continuing.持續修改中。1.stringbuffer 所處類層次 易忽略點 這個類是執行緒安全的。所有的method直接或間接加synchronized。所以我們如果是單執行緒情況下也考慮到這個會不會影響到效率。當然可能jit可以進行這個優化,待我接下來驗證。預設情況下乙個長為...
原始碼解析 JDK原始碼之LinkedHashMap
linkedhashmap原始碼,基於 jdk1.6.43 他繼承了hashmap,並且實現了插入和訪問的有序功能 public class linkedhashmapextends hashmapimplements map 其也有乙個entry內部類,繼承了 hashmap 的entry 內部類...