【金三銀四】HashMap圖解原理與數據結構二【JDK8紅黑樹】

約會被拒

上次給娜娜教完【金三銀四】《HashMap圖解原理與數據結構》之後,娜娜自信滿滿的去面試了。

今天我約娜娜出來看電影。娜娜沒心情。

娜娜面試又被虐了,辛巴哥哥很難受,因爲週末沒人陪我去看電影了,我決定要幫幫娜娜小姐姐。

回到過去

讓我們來回憶下上篇我們介紹的hashmap。

JDK1.8以前HashMap底層數據結構和算法:

數組+鏈表+哈希算法

數組

數組:採用一段連續的存儲單元來存儲數據。對於指定下標的查找,時間複雜度爲O(1);對於一般的插入刪除操作,
涉及到數組元素的移動,其平均複雜度也爲O(n)

在這裏插入圖片描述
Java代碼表示

   //數組:採用一段連續的存儲單元來存儲數據。
   //特點:指定下標O(1) 刪除插入O(N) 數組:查詢快 插入慢 ArrayList
   public static void main(String[] args) {
      Integer[] integers = new Integer[10];
      integers[0]=0;//王五
      integers[1]=1;
      integers[2]=2;
      integers[9]=9;

鏈表

鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的
對於鏈表的新增,刪除等操作(在找到指定操作位置後),僅需處理結點間的引用即可,時間複雜度爲O(1),
而查找操作需要遍歷鏈表逐一進行比對,複雜度爲O(n)

在這裏插入圖片描述

public class Node {

   public Node  next;
   private Object data;

   public Node(Object data) {
      this.data = data;
   }
   //鏈表:鏈表是一種物理存儲單元上非連續、非順序的存儲結構
   //特點:插入、刪除時間複雜度O(1) 查找遍歷時間複雜度0(N) 插入快 查找慢
   public static void main(String[] args) {
         Node node=new Node(15);
         node.next=new Node(1);
         node.next.next=new Node(9);
   }

哈希算法

哈希算法(也叫散列),就是把任意長度值(Key)通過散列算法變換成固定長度的key地址,通過這個地址進行訪問的數據結構。
它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。
在這裏插入圖片描述

JDK1.8以後HashMap底層數據結構變化:

數組+鏈表+紅黑樹+哈希算法 嗯新增了紅黑樹。

在這裏插入圖片描述

爲什麼要紅黑樹

在jdk7之前hashmap極端情況可能會出現這種情況

在這裏插入圖片描述
代碼表示形式爲:

在這裏插入圖片描述

鏈表過長會出現什麼問題了?

鏈表過長會出現遍歷過長,我們說一個算法好與壞時間複雜度來決定,而這種鏈表的特點是:插入快,查詢慢。所以其時間複雜度爲O(N)。如圖所示:
在這裏插入圖片描述

什麼是紅黑樹

紅黑樹定義和性質

紅黑樹是一種含有紅黑結點並能自平衡的二叉查找樹。它必須滿足下面性質:

  • 性質1:每個節點要麼是黑色,要麼是紅色。
  • 性質2:根節點是黑色。
  • 性質3:每個葉子節點(NIL)是黑色。
  • 性質4:每個紅色結點的兩個子結點一定都是黑色。
  • 性質5:任意一結點到每個葉子結點的路徑都包含數量相同的黑結點。

具體是怎麼樣存儲的,我們直接上圖 大家就明白了。

在這裏插入圖片描述

遍歷規則是:

小中大,左中右

在這裏插入圖片描述

根據上面鏈表和紅黑樹查找的規則,我們發現鏈表找到數字7需要查詢7次時間複雜度爲O(n),而我們的紅黑樹只需要查詢4次,時間複雜度爲O(logn)

HashMap 怎麼用紅黑樹的?

通過上訴列子我們發現紅黑樹是可以加快遍歷查詢速度的,因爲減少了次數,自然就提高了效率。但是hashmap並不是一上來就直接用紅黑樹的,來我們看下源碼。

在這裏插入圖片描述

put方法

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

大致源碼如圖所示。明白了嗎?明白了幫我點個贊或者評論下吧。

在這裏插入圖片描述

總結與調優:

當然我還要考考你,爲什麼要設置閾值8?爲什麼一上來還是鏈表了?而是達到閾值條件了才變成紅黑樹了?

這個問題其實跟魚和熊掌不可兼得一樣的道理:

鏈表:插入快、查詢慢

紅黑樹:查詢快、插入慢

也就是說紅黑樹雖然遍歷快,但是其插入的時候是沒有鏈表快的。因爲鏈表next引用即可,而紅黑樹需要數據左右交換。所以閾值int TREEIFY_THRESHOLD = 8; 的時候才變成紅黑樹,這個閾值是根據統計學定理來的哦?

你們想不想知道是什麼定理了?可以關注我們的公衆號:java大型網站架構 。裏頭有答案。

調優:

之前娜娜面試的時候被問到過,我們如何對hashmap在開發的時候性能優化?

答:如果我們知道查詢出來的數據是固定某個大小的,我們可以事先指定其大小,這樣可以加快對put

操作的效率。知道爲什麼嗎?歡迎評論哦
在這裏插入圖片描述

求關注

好了各位,以上就是這篇文章的全部內容了,能看到這裏的人呀,都是牛人。
白嫖不好,創作不易,各位的支持和認可,就是我創作的最大動力,我們下篇文章見!
微信搜索:Java大型網站架構
在這裏插入圖片描述
如果本篇博客有任何錯誤,請批評指教,不勝感激 !

發佈了23 篇原創文章 · 獲贊 144 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章