Java容器源碼分析-HashMap vs TreeMap vs LinkedHashMap

        這裏我採用的分析方式是帖子博客加上本身翻看jdk源碼。有些狀況下寫一些測試的算法小例子加深印象。我這裏只描述一下本身的總結想法     html

        上一篇文章咱們研究了set接口下的幾個容器,因爲其Set集合設計時底層的數據模型是Map,Set的實現是基於Map的、因此先搞懂Map、才能去理解Set、不然的話、直接去弄Set會以爲雲裏霧裏、最後發現是浪費時間。這一節介紹關於Map的相關接口、抽象類的功能。java

 1、Map集合結構體系圖(網絡圖,侵刪)算法

         這篇文章主要對TreeMap,HashMap和LinkedHashMap作分析,其餘不經常使用的先不進行分析,另外針對HashTable和ConcurrentHashMap這兩個線程安全的Map着重開一章去整理數組

2、源碼分析 安全

       一、HashMap源碼分析網絡

            上帖子:http://www.cnblogs.com/chengxiao/p/6059914.html數據結構

            總結:源碼分析

            (1)首先重點了解一下哈希表的數據結構,測試

                     哈希表(散列)主要利用數組和鏈表的方式。利用這種方式就能夠避免單個數組出現的修改刪除的高時間複雜度,又避免了聊表查詢的高時間複雜度,具體實現方式請參看上邊的博客,具體的講解了目前的主要數據結構以及哈希表結構.net

            (2)知道了哈希表的數據結構,就能理解HashMap的存儲方式了,HashMap就是利用數組+鏈表的方式進行數據存儲。博客中也對主要的添加,刪除,修改方法進行了源碼詳解。在看源碼的過程當中注意細節

  • 方法沒有加鎖,因此對於hashMap來講,是線程不安全的集合
  • 數組是如何擴容的,擴容的算法如博客  http://www.cnblogs.com/hzmark/archive/2012/12/24/HashMap.html
  • 對於hash碰撞是如何處理的,
    Hashmap裏面的bucket出現了單鏈表的形式,散列表要解決的一個問題就是散列值的衝突問題,一般是兩種方法:鏈表法和開放地址法。鏈表法就是將相同hash值的對象組織成一個鏈表放在hash值對應的槽位;開放地址法是經過一個探測算法,當某個槽位已經被佔據的狀況下繼續查找下一個可使用的槽位。java.util.HashMap採用的鏈表法的方式,鏈表是單向鏈表。
    hash碰撞的產生和解決:http://blog.csdn.net/luo_da/article/details/77507315
  • hash與hashCode的重寫
    重寫對象的equels必須重寫hashCode方法,否則比對後沒法識別是否是同一個對象
    hashCode重寫例子:http://blog.csdn.net/woshixuye/article/details/8189398

   二、LinkedHashMap源碼分析

         發佈一個描述LinkedHashMap的博客:http://www.cnblogs.com/chenpi/p/5294077.html

  • LinkedHashMap繼承了HashMap,在它的構造方法中調用的都是父類HashMap的構造方法
  • LinkedHashMap也採用數組加鏈表的方式,只不過LinkedHashMap在散列表基礎上多維護了一個有序雙向鏈表,因此LinkedHashMap支持排序。能夠按照插入循序排序和訪問數序排序
    源碼分析:http://www.cnblogs.com/chenpi/p/5294077.html
  • LinkedHashMap一樣沒有同步方法,不支持線程安全
  • hash碰撞原理同於HashMap

   三、TreeMap源碼分析

         發佈一個描述TreeMap的博客:http://www.cnblogs.com/wzyxidian/p/5204879.html

  • TreeMap是採用一個「紅黑樹」的數據結構進行存儲,存儲對象對擁有它的父節點,左孩子,右孩子,具體的二叉樹的實現原理請參考博客中有詳解,這裏不作過多解析
  • TreeMap是線程不安全的

 3、區別對比

      一、相同點

  • 都是線程不安全的
  • LinkedHashMap和HashMap都是採用散列表的結構進行數據存儲

      二、不一樣點

  • TreeMap存儲方式採用鏈表的方式進行存儲,而LinkedHashMap和HashMap採用散列表的結構存儲
  • HashMap存儲是無序的,LinkedHashMap能夠按照插敘順序排序,TreeMap按照key的天然排序或者自定義排序(只須要key定製排序Comparator )

4、總結

      三種類型分別在何時使用

  一、通常狀況下,咱們用的最多的是HashMap。HashMap裏面存入的鍵值對在取出的時候是隨機的,它根據鍵的HashCode值存儲數據,根據鍵能夠直接獲取它的值,具備很快的訪問速度。在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。
  二、TreeMap取出來的是排序後的鍵值對。但若是您要按天然順序或自定義順序遍歷鍵,那麼TreeMap會更好。
   三、LinkedHashMap 是HashMap的一個子類,若是須要輸出的順序和輸入的相同,那麼用LinkedHashMap能夠實現,它還能夠按讀取順序來排列,像鏈接池中能夠應用。

相關文章
相關標籤/搜索