上文講到HashMap的增長方法,如今繼續 上文連接html
HashMap在上一篇源碼分析的文章中,若是使用put的時候若是元素數量超過threshold就會調用resize進行擴容java
想要了解HashMap的擴容機制你要有這兩個問題數組
在添加元素的時候若是超過threshold設置的閥值點就會進行擴容,簡單的來講就是一個水壺容量是二升,而後這個時候已經滿了可是你還要繼續加水,咋辦?換個大的。因此HashMap的擴容就和你這個水壺同樣,水已經滿了那我就在換個大的水壺繼續加水。不過在你換水壺的時候是有不少條件的。安全
在我看這個resize的源碼的時候我也是一臉懵逼,最後請教了大佬獲得的回答是由於1.8加入了紅黑樹比較麻煩能夠看一下1.7的,而後我有去網上看了一下別人寫的文章基本上都是基於1.7的resize。因此這裏就看1.7的resize來分析。數據結構
來看JDK1.7中resize的實現。源碼分析
複製操做是調用的transfer方法線程
在1.7中的resize結合一下咱們的小例子能夠這樣理解,去超市買一個大一點的水壺,而後把之前水壺裏面的水給倒進新的水壺裏面。再把咱們當前的水壺的容量替換掉,告訴別人個人容量更大了。(強行比喻哈哈哈哈哈)3d
1.7中的resize就是這麼簡單,那咱們在看一下1.8中的resize(),這樣再看就不會一臉懵逼了code
我在這裏把1.8的resize方法分爲兩部分htm
第一部分
第二部分
對比一下1.7
刪除的話就是首先先找到元素的位置,若是是鏈表就遍歷鏈表找到元素以後刪除。若是是用紅黑樹就遍歷樹而後找到以後作刪除,樹小於6的時候要轉鏈表。
刪除方法:
調用removeNode:
查找方法,經過元素的Key找到Value。
調用getNode()方法
看完能夠知道邏輯是先經過Key計算出索引的位置,而後先檢查第一個節點看看是不是咱們要的節點,若是不是在去查看是否死紅黑樹和鏈表。
咱們經過下面幾個例子來演示一下HashMap怎麼遍歷
1.分別遍歷Key和Values
for (String key:map.keySet()){ System.out.println(key); } for (Object value : map.values()) { System.out.println(value); }
2.迭代
Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Object> mapEntry = iterator.next(); System.out.println(mapEntry.getKey() + "====" + mapEntry.getValue()); }
3.獲取 key 集合
Set<String> keySet = map.keySet(); for (String str : keySet) { System.out.println(str + "====" + map.get(str)); }
4.獲取Entry 集合,遍歷Entry 集合
Set<Map.Entry<String, Object>> entrySet = map.entrySet(); for (Map.Entry<String, Object> entry : entrySet) { System.out.println(entry.getKey() + "====" + entry.getValue()); }
對比來講使用迭代的方式是最好的,也能夠在迭代的時候對集合的元素進行刪除
基於JDK1.8的HashMap是由數組+鏈表+紅黑樹組成,當鏈表長度超過 8 時會自動轉換成紅黑樹,當紅黑樹節點個數小於 6 時,又會轉化成鏈表。相對於早期版本的 JDK HashMap 實現,新增了紅黑樹做爲底層數據結構,在數據量較大且哈希碰撞較多時,可以極大的增長檢索的效率。HashMap並非線程安全的,支持K和V爲null ,k重複會覆蓋,V能夠重複,還有一點HashMap遍歷的數據不是有序的是無序的