1. 程式人生 > >jdk1.8 hashmap.treeifyBin原始碼

jdk1.8 hashmap.treeifyBin原始碼

final void treeifyBin(Node<K,V>[] tab, int hash) {
        int n, index; Node<K,V> e;//n是陣列長度,e是hash值和陣列長度計算後,得到連結串列的首節點
        /** 如果陣列為空或者陣列長度小於樹結構化的最小限制
		* MIN_TREEIFY_CAPACITY 預設值64,對於這個值可以理解為:如果元素陣列長度小於這個值,沒有必要去進行結構轉換
		* 當一個數組位置上集中了多個鍵值對,那是因為這些key的hash值和陣列長度取模之後結果相同。(並不是因為這些key的hash值相同)
		* 因為hash值相同的概率不高,所以可以通過擴容的方式,來使得最終這些key的hash值在和新的陣列長度取模之後,拆分到多個數組位置上。
		*/
	    if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
            resize();
        // 如果元素陣列長度已經大於等於了 MIN_TREEIFY_CAPACITY,那麼就有必要進行結構轉換了
    	// 根據hash值和陣列長度進行取模運算後,得到連結串列的首節點
        else if ((e = tab[index = (n - 1) & hash]) != null) {
            TreeNode<K,V> hd = null, tl = null;//hd是樹首節點,tl是樹尾節點
            do {
                TreeNode<K,V> p = replacementTreeNode(e, null);//節點轉換為樹節點
                if (tl == null)//如果樹尾節點為空說明沒有根節點
                    hd = p;//附值給首節點,樹的根節點
                else {// 尾節點不為空,以下兩行是一個雙向連結串列結構
                    p.prev = tl;//雙鏈表,prev指向前一個節點,尾節點
                    tl.next = p;//next指向下一個節點,當前節點
                }
                tl = p;// 把當前節點設為尾節點
            } while ((e = e.next) != null);
            // 到目前為止 也只是把Node物件轉換成了TreeNode物件,把單向連結串列轉換成了雙向連結串列
       		// 把轉換後的雙向連結串列,替換原來位置上的單向連結串列
            if ((tab[index] = hd) != null)
                hd.treeify(tab);//轉換成紅黑樹
        }
    }

參考老艮頭的JDK8:HashMap原始碼解析:treeifyBin方法https://blog.csdn.net/weixin_42340670/article/details/80503863