HashMap學習 — 單向列表轉化為雙向列表


一、概覽

  HashMap的某個桶位如果存儲的是單向列表,當向這個桶位繼續插入一個元素的時候,這個桶位元素的數量超過

  

  8時,單項列表會轉化為紅黑樹(同時是一個雙向列表,jdk1.8之后),且會先轉化為雙向列表:

  

 

二、轉化過程

  1,運行如下程序,使map底層數組的某個桶位的單向列表”開始“轉化為紅黑樹

  

   按道理,當map-put的元素超過 8*100 = 800時才會擴容數組,所以,當map.put(65, "65")時,table[1]的位置將會是:

  

  此時,table[1]的元素數量(9個)超過8(TREEIFY_THRESHOLD),這個單向列表會被轉化為紅黑樹,但是受

  

  這個數字的影響,數組的長度(現在為8)只有擴容到64之后,才會將單向列表會被轉化為紅黑樹;擴容的過程:參考(參考http:還沒寫好)。

  當map.put(513, "513")時,table[1]的位置將會是:

  

 

   此時,table[1]的元素數量(9個)超過8(TREEIFY_THRESHOLD),這個單向列表”將會“被轉化為紅黑樹。

 

  2,單向列表轉化為紅黑樹

  先轉化為雙向鏈表,雙向鏈表轉化為紅黑樹,參考:http:還沒有寫好;

  jdk1.8 - HashMap源代碼如下紅框所示:

  

  e:tab[1],是一條單向鏈表,如上面數組的那個示意圖,節點都是Node類型,隨着單向列表不斷的遞進,指向的當前單向列表的節點;

  hd:head?頭部節點,雙向列表的頭部節點,節點是TreeNode類型;

  tl:tail?尾部節點,雙向列表的尾部節點,節點是TreeNode類型;

  p:e當前指向的單向列表的節點轉化為TreeNode類型后的節點;

 

  2.1,Node和TreeNode的聯系與區別

   Node: 

 

  TreeNode:, 

 

  TreeNode是Node的子類,也就是說TreeNode含有Node的所有屬性;

  Node是一個含有next屬性的單向列表,TreeNode是一個含有next(繼承自Node)、prev屬性的雙向鏈表,同時TreeNode還是一個含有left、right、parent屬性的二叉樹,同時TreeNode還是一個含有boolean red屬性的紅黑樹(在二叉樹的基礎上)。

 

  2.2,單向列表開始轉化為雙向鏈表

  p的來源:

  1,第一次循環

  

   2,第二次循環

  

  3,第三次循環

  

   4,以此類推

  總結下來,就是:

  A、讓單向列表遞進,使用局部變量(中間變量)e指向遞進過程中的某個節點;

  B、使用中間變量p,根據步驟A中的e構造出一個雙向鏈表的節點(當前還沒有掛到雙向列表上);

  C、如果雙向鏈表的尾部為空,即雙向鏈表沒有任何節點,則讓步驟B中的p既作為頭也作為尾;

    如果雙向鏈表的尾部不為空:則需要將步驟B中的p掛到雙向列表的尾部;

  D、最后,由於雙向列表的尾部發生了變化,需要將tl指向新的尾部節點。

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM