咱們通常在寫代碼時,使用HashMap數據結構存數據時,有時候不會作容量大小設置,這樣可能會形成一些內存浪費,因此,在知道存儲的鍵值對數量的狀況下,作初始化比較好。
新建一個hashMap的時候,能夠經過initialCapacity設置hashMap長度的初始化值。算法
Map<String, Object> resultMap = new HashMap<String, Object>(initialCapacity: 5);
hashMap源碼中initialCapacity的初始值爲16,負載因子爲0.75;數組
因此一個hashMap中默認存儲長度爲16 * 0.75 = 12,也就是若是hashMap.put的鍵值對數量小於12的時候,hashMap位置夠用;可是當添加的鍵值對數超過12後,hashMap須要擴容,一倍,也就是長度從12擴容到24;數據結構
例如鍵值對一共13個,這樣剩餘11個位置性能都浪費了,那麼若是已知須要添加的鍵值對數量,就能夠經過設置initialMap的值,來避免hashMap擴容,減小性能消耗。性能
咱們須要往hashMap中添加6個鍵值對,6 / 0.75 = 8;那就能夠把initialCapacity設置爲9比較合適,節省性能。code
公式是《阿里巴巴Java開發手冊》中的一個建議,在Guava中也是提供了相同的算法,更甚之,這個算法其實是JDK8中putAll()方法的實現。這是公式的得出是由於,當HashMap內部維護的哈希表的容量達到75%時(默認狀況下),就會觸發rehash(重建hash表)操做。而rehash的過程是比較耗費時間的。因此初始化容量要設置成expectedSize/0.75 + 1 的話,能夠有效地減小衝突,也能夠減少偏差"。內存
個人理解是:當數組長度是可容納長度的75%時,就會從新創建數組,產生額外開銷,因此這個預期的數組長度要小於可容納的長度的75%,也就是 (initialCapacity - 1 ) * 0.75 = 預期數組長度 ,即 initialCapacity * 0.75 > 預期數組長度ci
最後,千言萬語都匯成最後這一個容量公式:開發
initialCapacity = expectedSize/0.75 + 1