HashMap,為什么要設置初始容量,容量設置為多大更好


我們日常經常定義hashMap,是這樣的:

Map<String,String> map = new HashMap<>();

可是就是這樣一句簡單的代碼,都可以優化,那就是給map設置初始容量大小。比如:

Map<String,String> map = new HashMap<>(4);

當用代碼檢查工具掃描時,也會提醒你設置初始容量

一、如果不設置初始大小,那默認大小是多大?

1、如果不設置初始容量,那么構造方法是這樣的:

 即,所有Map相關屬性全部用默認值

2、當put第一個元素時,因為map的Node<K,V>[] table為空,所以需要resize()

  3、接下來走resize方法,因為其他屬性都為默認值,所以容量大小會設置為:DEFAULT_INITIAL_CAPACITY

 我們可以看到這個值默認為16 

 所以,這時的map的node數組,是一個容量為16的數組

二、如何擴容的

1、看一下put方法

 當元素個數>threshold時,會觸發擴容。

擴多大呢?代碼會走到這里:

 即:擴容到原容量的2倍。

 

回答標題的問題:為什么要設置初始容量?

  1、如果你的map只需要put幾個元素,那么這樣就會造成容量的浪費。

  2、如果你的map需要put成百上千個元素,那么這個map就會不斷擴容(從16、32、64、128...),擴容需要創建新數組,並且rehash等操作,這樣會導致一些性能的浪費。

  所以,如果在寫代碼時,如果能夠預估map的容量,就可以盡量去設置他的容量大小,這樣可以減少容量浪費減少擴容次數

3、初始容量設置為多大?

通過上面的內容可以看到,當元素個數超過總容量的0.75倍時,會觸發擴容,此時容量為此前的2倍。

通過測試,也證實了如上的說法:

當元素為1時,擴容大小為2。

當元素為2時,擴容大小為4。

當元素為3時,擴容大小為4。

當元素為4時,擴容大小為8。

當元素為5時,擴容大小為8。

當元素為6時,擴容大小為8。

當元素為7時,擴容大小為16。(7 > 8 * 0.75)

。。。

所以如何設置一個初始容量,從而減小擴容次數呢?

設置容量的大小應該是:

1、預估元素個數,m(比如:5)

2、取離m最近的2的n次方的值:x(比如:8)。

3、如果大於 m>0.75x,則x=x*2

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM