java進階(29)–HashMap集合
一、HashMap簡介
1、HashMap底層是哈希表結構,類似字典,初始化如下:
2、哈希表結構:
是一個數組+單向鏈表的結構體
數組:查詢效率較高,隨機增刪效率很低
單向鏈表:在隨機增刪方面效率較高,查詢方面效率很低
哈希表將以上兩種數據結構融合在一起,充分發揮它們各自的優點。
3、HashMap集合底層是數組,Node<k,v>[]tables;
hash為哈希值,是HashCode方法執行的結果,通過哈希演算法可以轉換為數組的下標;
key,value為Map的key與value,next為下一個記憶體地址
4、map.put(k,v)的實現原理
k,v封裝到Node對象內,底層調用hashCode()方法得出hash值,通過哈希演算法/哈希函數,將hash值轉換成數組下標。
如果下標對應的位置上面沒有元素,Node添加到位置上;
如果下標對應的位置上有鏈表,拿k與鏈表每個節點k進行equals,如所有equals方法都false,新節點將添加到尾部;
如果有一個euals返回true,那麼這個節點的value值將會覆蓋
5、map.get(k)的實現原理
調用k的hashCode()方法得出哈希值,通過哈希演算法轉換成數組下標,通過數組下標快速定位到某個位置,位置上什麼都沒有話,返回null;
如果這個位置上有單向鏈表,那麼會拿著參數k和單向鏈表上每個節點的k進行equals,如果所有的equals返回false,囊二get方法返回null。
主要其中某一個節點的k和參數k equals返回true,那麼此時這個節點的value就是我們要找的value,既為get方法的最終返回value
6、HashMap的key部分元素需要重寫equals方法hashCode方法。也就是hashSet集合中的元素需要重寫equals方法hashCode方法。
7、HashMap使用不當時會發生性能問題:
假設所有的hashCode方法返回值都相等,那麼底層會變成單向鏈表,即散列分布不均勻。
什麼是散列分布均勻:100個元素,10個單向鏈表,每個單向鏈表中包含10個節點。
假設所有的hashCode方法返回均不一樣,那麼底層會變成數組,即散列分布不均勻。
散列分布均勻需要重寫hashCode方法有一定的技巧
8、HashMap集合底層數組達到75%容量時,數組是開始擴容,默認數組容量為16,初始化容量必須是2的倍數,為達到散列分布均勻,且可以提高hashMap集合存取效率。
9、HashMap元素存取什麼時候不需要執行equals方法:k.hashCode方法返回的哈希值的數組下標位置為null的時候,equals不再需要執行。
10、HashMap JDK8改進:
如果哈希表的單向鏈表中元素>8,單向鏈表會變成紅黑樹,當紅黑樹上節點數量<6,會重新把紅黑數變成單向鏈表
11、哈希表數據結構注意事項:
如果o1與o2的hash值相同,一定在同一個單向鏈表上,
如果o1與o2的hash值不同,但由於哈希演算法執行結束後轉換的數組下標可能相同,此時會發生「哈希碰撞」
二、實例說明:
1、測試HashMap元素特點:key為integer,它的hashCode與equals均已經被重寫
2、遍歷Map集合-元素將被無須取出
3、重寫quals與hashCode方法
未重寫hashCode與equals
重寫hashCode與equals後
4、HashMap的key與value可以為空嗎,
HashMap可以,Hashtable則不行