Java中的常見五種map容器源碼分析總結(HashMap、Hashtable、ConcurrentHashMap、LinkedHashMap、TreeMap)

  斷斷續續寫了半個月,今天終於把TreeMap容器中的紅黑樹搞定了,現在來水一篇又快又短Java Map容器總結博客 😂😂。

註明:本篇博客不會涉及容器的源碼什麼的,主要是總結各個map容器的底層實現特點、主要運用場景。如果你需要詳細瞭解更多關於Java中的map容器實現的細節,文末會提供我前面寫的源碼分析的博客鏈接,歡迎閱讀。

一、Java中的Map容器概述

  Map是一種存儲key-value鍵值對)的容器,在Java中,常見的Map接口的實現類有五種,分別是HashMapHashtableConcurrentHashMapLinkedHashMapTreeMap。五種容器的關係如下圖:
在這裏插入圖片描述
  順帶一提,貌似有不少人覺得map就是hashmaphashmap就是map,把hashmap兩個概念混爲一談。然而map是用於存儲key-value的虛擬容器,按照key的hash值將節點散列到一個table數組(也稱hash表)的table[i](也稱hash桶)中。等你看完TreeMap的底層數據結構就會發現,不通過key.hash值,也可以實現map容器

二、HashMap容器

1、HashMap概述

  Java中的HashMap底層使用一個table數組存放節點,使用鏈表(JDK 1.8新增紅黑樹)解決hash衝突(多個元素的hash值散列到同一個table[i]中)的問題。

2、HashMap數據結構示意圖

在這裏插入圖片描述

3、HashMap特點

  • ①、存取高效,不支持併發讀寫操作(沒有引入鎖任何機制)
  • ②、table數組的長默認是16,並且每次擴容爲原來的2倍(長度總是保持爲2的次冪,方便hash值求餘)
  • ③、支持key、value爲null的鍵值對插入

4、HashMap源碼分析鏈接

Java容器之HashMap源碼分析(媽媽再也不用擔心我不懂HashMap了)

三、Hashtable容器

1、Hashtable概述

  Java中的Hashtable底層同樣是使用一個table數組存放節點,使用鏈表解決hash衝突(多個元素的hash值散列到同一個table[i]中)的問題。不過引入了鎖機制(通過synchronized關鍵字,鎖爲this,每次鎖住整個容器),支持併發操作。

2、Hashtable數據結構示意圖

在這裏插入圖片描述

3、Hashtable特點

  • ①、寫入、刪除效率相對較低。引入鎖機制,通過synchronized關鍵字修飾方法(同步方法),鎖對象爲this,每次鎖住整個容器,鎖的粒度太大。
  • ②、table數組的長默認是11,並且每次擴容爲原來的2倍 + 1
  • ③、不支持key、value爲null的鍵值對插入

4、Hashtable源碼分析鏈接

Java容器之Hashtable源碼分析(關於Hashtable的這些細節你可能還不知道)

四、ConcurrentHashMap容器

1、ConcurrentHashMap概述

  Java中的ConcurrentHashMap底層同樣是使用一個table數組存放節點,使用鏈表解決hash衝突(多個元素的hash值散列到同一個table[i]中)的問題。在JDK 1.8前的版本中引入段的概念,使用RententLock鎖,並且分段鎖(對每個段分別設置一個鎖),相比於Hashtable鎖整個容器,併發操作時,效率提高了不少。
  在JDK 1.8的時候,又取消了段的概念,重新使用synchronized關鍵字(同步代碼塊)。不過每次鎖住的對象的是需要修改的table[i]hash桶),並且在各大方法中儘量減少了同步代碼塊中的代碼量,從而減少了鎖的粒度,併發操作時,效率提高了不少。在擴容時,支持多個線程同時進行擴容(併發擴容)。

2、ConcurrentHashMap數據結構示意圖

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

3、ConcurrentHashMap特點

  • ①、寫入、刪除效率相比與Hashtable容器較高。引入鎖機制,通過synchronized關鍵字(同步代碼塊),鎖對象爲即將修改的table[i](hash桶),鎖的粒度小。
  • ②、table數組的長默認是16,並且每次擴容爲原來的2倍(長度總是保持爲2的次冪,方便hash值求餘)
  • ③、不支持key、value爲null的鍵值對插入

4、ConcurrentHashMap源碼分析鏈接

Java容器之ConcurrentHashMap源碼分析(JDK 1.7與JDK 1.8對比)

五、LinkedHashMap容器

1、LinkedHashMap概述

  Java中的LinkedHashMapHashMap的子類,也可以說是對HashMap的封裝。對外展示的是一個雙向鏈表,鏈表中的元素順序,就是插入節點的順序。

2、LinkedHashMap數據結構示意圖

在這裏插入圖片描述

3、LinkedHashMap特點

  • ①、LinkedHashMap是對HashMap的進一步封裝,所以實現細節基本一致
  • ②、對外展示爲雙向鏈表,鏈表節點中的順序爲插入時的順序(其實也可以修改爲訪問順序)

4、LinkedHashMap源碼分析鏈接

Java容器之LinkedHashMap源碼分析(看看確定不點進來?進來真不點?)

六、TreeMap容器

1、TreeMap概述

  Java中的TreeMap容器底層是通過維護一棵紅黑樹來存儲key-value節點,與hash沒有任何關係。樹中的節點按照key的大小排序,可以手動指定key的比較器comparator

2、TreeMap數據結構示意圖

在這裏插入圖片描述

3、TreeMap特點

  • ①、讀寫高效,查找的複雜度在O(log2n)級別。(不支持併發讀寫,爲引入鎖)
  • ②、節點按照key升序排列,可指定key的比較器comparator
  • ③、不支持key爲null的key-value插入

4、TreeMap源碼分析鏈接

Java容器之TreeMap源碼分析(附紅黑樹調整圖解)

七、總結

  HashMapLinkedHashMapHashtableConcurrentHashMap這四個都是通過table數組,並結合hash散列存放節點,前兩者不支持併發讀寫,效率較高,後兩者支持併發,並且ConcurrentHashMap的效率更高些。TreeMap容器通過紅黑樹存儲key-value節點,節點按照key的大小排序,查找、插入比較高效,時間複雜度在O(log2n)級別。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章