一、初窺HashMap
HashMap是應用更廣泛的哈希表
實現,而且大部分情況下,都能在常數時間性能的情況下進行put和get操作。要掌握HashMap,主要從如下幾點來把握:
- jdk1.7中底層是由數組(也有叫做“位桶”的)+鏈表實現;jdk1.8中底層是由數組+鏈表/紅黑樹實現
- 可以存儲null鍵和null值,線程不安全。在HashMap中,null可以作爲鍵,這樣的鍵只有一個,但可以有一個或多個鍵所對應的值爲null。
當get()方法返回null值時,即可以表示HashMap中沒有該key,也可以表示該key所對應的value爲null
。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個key,應該用containsKey()
方法來判斷。而在Hashtable中,無論是key還是value都不能爲null。 - 初始size爲16,擴容:newsize = oldsize*2,
size一定爲2的n次冪
- 擴容針對整個Map,每次擴容時,原來數組中的元素依次重新計算存放位置,並重新插入
- 插入元素後才判斷該不該擴容,有可能無效擴容(插入後如果擴容,如果沒有再次插入,就會產生無效擴容)
- 當Map中元素總數超過Entry數組的75%,觸發擴容操作,爲了減少鏈表長度,元素分配更均勻
- 1.7中是先擴容後插入新值的,1.8中是先插值再擴容
爲什麼說HashMap是線程不安全的?
在接近臨界點時,若此時兩個或者多個線程進行put操作,都會進行resize(擴容)和reHash(爲key重新計算所在位置),而reHash在併發的情況下可能會形成鏈表環
。總結來說就是在多線程環境下,使用HashMap進行put操作