問題1:HashM安排的初始長度,為什么?
初始長度是 16,每次擴展或者是手動初始化,長度必須是 2的冪。
因為: index = HashCode(Key) & (length - 1), 如果 length是 2的 冪的話,則 length - 1就是 全是 1的二進制數,比如 16 - 1 = 1111,這樣相當於是 坐落在長度為 length的hashMap上的位置只和 HashCode的后四位有關,這只要給出的HashCode算法本身分布均勻,算出的index就是分布均勻的。
因為HashMap的key是int類型,所以最大值是2^31次方,但是查看源碼,當到達 2^30次方,即
MAXIMUM_CAPACITY,之后,便不再進行擴容。
問題2:高並發情況下,為什么HashMap出現死鎖?
我們看到默認HashMap的初始長度是16,比較小,每一次push的時候,都會檢查當前容量是否超過 預定的 threshold,如果超過,擴大HashMap容量一倍,整個表里的所有元素都需要按照新的hash算法被算一遍,這個代價較大。提到死鎖,對於 HashMap來說,貌似只能和鏈表操作有關。
正常ReHash過程,可以看到,每個元素重新算hash值,將鏈表翻轉(目的遍歷每個bucket上的鏈表還是用的是頭插法,時間復雜度最低),放到對應的bucket上的鏈表中
問題3:java8對hashMap做了什么優化?
簡單說: java7中 hashMap每個桶中放置的是鏈表,這樣當hash碰撞嚴重時,會導致個別位置鏈表長度過長,從而影響性能。
java8中,HashMap 每個桶中當鏈表長度超過8之后,會將鏈表轉換成紅黑樹,從而提升增刪改查的速度。
參考來源:http://www.mamicode.com/info-detail-2120749.html