HashMap源碼淺讀

0 閱讀須知


​ 學習過數據結構的童鞋一定對哈希表有所瞭解,Java1.7中的HashMap就是對數據結構中的哈希鏈表的實現,但是由於Java1.7中的HashMap存在着一些問題,故在Java1.8中做出了修改。本篇就讓我們一起來通過學習Java中HashMap的源碼來較爲深入的理解hashMap的設計思路。

單詞識記

單詞 漢譯
encapsulated 封裝
load factor 負荷因子
capacity 容量

1 HashMap實現


  • JDK1.7中HashMap採用數組+鏈表的方式來實現最經典的哈希表
  • JDK1.8中爲了應對JDK1.7中的一些問題,採用數組+鏈表+紅黑樹實現

注意:HashMap的容量必須是2^n默認是16,原因是HashMap中爲了提高效率更快定位出key的位置,採用&運算來獲取key對應數組的位置。下圖是JDK1.8中源碼:可以看出(n-1)&hash就是在這個關鍵點上。
在這裏插入圖片描述
在這裏插入圖片描述

JDK1.7問題

  1. 併發環境中易死鎖
  2. 可以通過精心構造的惡意請求引發DoS,造成安全問題

引發以上問題的關鍵是在HashMap中佔用的key數達到capacity*load factor時就開始擴容,在單線程下的擴容沒有什麼影響,但是在多線程下擴容就可能帶來鏈環,如果正好get查詢到了鏈環就進入了死循環。具體請參考:https://coolshell.cn/articles/9606.html

2 JDK1.8解決方案


​ 在JDK1.8中對HashMap進行擴容resize操作的時候,保證原有鏈表的前後順序不能變,這樣就可以有效的防止出現環形鏈表,但是HashMap仍然是線程不安全的。源碼如下:(目前還沒怎麼看懂,但是從註釋的來看就是保證了鏈表順序)
在這裏插入圖片描述

注意:HashMap中的resize方法非常影響性能,儘量在創建之初提供較大的空間。

3 總結


​ 本篇從HashMap的源碼入手,簡單瞭解了一下JDK1.7–JDK1.8的變化,同時也提供了我們一個新的學習方法:閱讀源碼。

​ 不斷提升自我,迭代自我,我是猿同學~~~

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