jdk1.8 HashMap 實現 數組+鏈表/紅黑樹


轉載至 http://www.cnblogs.com/leesf456/p/5242233.html

一、前言

  在分析jdk1.8后的HashMap源碼時,發現網上好多分析都是基於之前的jdk,而Java8的HashMap對之前做了較大的優化,其中最重要的一個優化就是桶中的元素不再唯一按照鏈表組合,也可以使用紅黑樹進行存儲,總之,目標只有一個,那就是在安全和功能性完備的情況下讓其速度更快,提升性能。好~下面就開始分析源碼。

二、HashMap數據結構

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  說明:上圖很形象的展示了HashMap的數據結構(數組+鏈表+紅黑樹),桶中的結構可能是鏈表,也可能是紅黑樹,紅黑樹的引入是為了提高效率。所以可見,在分析源碼的時候我們不知不覺就溫習了數據結構的知識點,一舉兩得。

三、HashMap源碼分析

  3.1 類的繼承關系 

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

  可以看到HashMap繼承自父類(AbstractMap),實現了Map、Cloneable、Serializable接口。其中,Map接口定義了一組通用的操作;Cloneable接口則表示可以進行拷貝,在HashMap中,實現的是淺層次拷貝,即對拷貝對象的改變會影響被拷貝的對象;Serializable接口表示HashMap實現了序列化,即可以將HashMap對象保存至本地,之后可以恢復狀態。

  3.2 類的屬性 

 

 View Code

 

 

  說明:類的數據成員很重要,以上也解釋得很詳細了,其中有一個參數MIN_TREEIFY_CAPACITY,筆者暫時還不是太清楚,有讀者知道的話歡迎指導。

  3.3 類的構造函數

  1. HashMap(int, float)型構造函數

 View Code

  說明:tableSizeFor(initialCapacity)返回大於initialCapacity的最小的二次冪數值。

 View Code

  說明:>>> 操作符表示無符號右移,高位取0。

  2. HashMap(int)型構造函數。

 View Code

  3. HashMap()型構造函數。

 View Code

  4. HashMap(Map<? extends K>)型構造函數。

 View Code

  說明:putMapEntries(Map<? extends K, ? extends V> m, boolean evict)函數將m的所有元素存入本HashMap實例中。 

 View Code

  3.4 重要函數分析

  1. putVal函數  

 View Code

  說明:HashMap並沒有直接提供putVal接口給用戶調用,而是提供的put函數,而put函數就是通過putVal來插入元素的。

  2. getNode函數

 View Code

  說明:HashMap並沒有直接提供getNode接口給用戶調用,而是提供的get函數,而get函數就是通過getNode來取得元素的。

  3. resize函數  

 View Code

  說明:進行擴容,會伴隨着一次重新hash分配,並且會遍歷hash表中所有的元素,是非常耗時的。在編寫程序中,要盡量避免resize。

  在resize前和resize后的元素布局如下

  說明:上圖只是針對了數組下標為2的桶中的各個元素在擴容后的分配布局,其他各個桶中的元素布局可以以此類推。

四、針對HashMap的思考

  4.1. 關於擴容的思考

  從putVal源代碼中我們可以知道,當插入一個元素的時候size就加1,若size大於threshold的時候,就會進行擴容。假設我們的capacity大小為32,loadFator為0.75,則threshold為24 = 32 * 0.75,此時,插入了25個元素,並且插入的這25個元素都在同一個桶中,桶中的數據結構為紅黑樹,則還有31個桶是空的,也會進行擴容處理,其實,此時,還有31個桶是空的,好像似乎不需要進行擴容處理,但是是需要擴容處理的,因為此時我們的capacity大小可能不適當。我們前面知道,擴容處理會遍歷所有的元素,時間復雜度很高;前面我們還知道,經過一次擴容處理后,元素會更加均勻的分布在各個桶中,會提升訪問效率。所以,說盡量避免進行擴容處理,也就意味着,遍歷元素所帶來的壞處大於元素在桶中均勻分布所帶來的好處。如果有讀者有不同意見,也歡迎討論~


免責聲明!

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



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