從源代碼看HashMap的加載因子和容量分配

一直知道HashMap有默認的容量和加載因子,今天想看看源代碼,希望能了解的更清楚一些。

我們先看看默認的構(gòu)造器吧,以下為我本機的JDK6.0的源代碼.

歡迎訪問老紫竹的網(wǎng)站(http://www.java2000.net)和我在CSDN的博客(http://blog.csdn.net/java

/**

*?默認的初始化的容量,必須是2的冪次數(shù)

*?The?default?initial?capacity?-?MUST?be?a?power?of?two.

*/

staticfinalintDEFAULT_INITIAL_CAPACITY?=16;

/**

*?默認的加載因子

*/

staticfinalfloatDEFAULT_LOAD_FACTOR?=0.75f;

/**

*?下一個需要重新分配的尺寸值。等于容量乘以加載因子。

*?也就是說,一旦容量到了這個數(shù)值,將重新分配容器的尺寸。

*?The?next?size?value?at?which?to?resize?(capacity?*?load?factor).

*?@serial

*/

intthreshold;

publicHashMap()?{

this.loadFactor?=?DEFAULT_LOAD_FACTOR;

threshold?=?(int)(DEFAULT_INITIAL_CAPACITY?*?DEFAULT_LOAD_FACTOR);

table?=newEntry[DEFAULT_INITIAL_CAPACITY];

init();

}

歡迎訪問老紫竹的網(wǎng)站(http://www.java2000.net)和我在CSDN的博客(http://blog.csdn.net/java

從代碼可以看出,默認的容量是16,而 threshold是16*0.75 = 12;

我們來看看增加的部分代碼。

publicV?put(K?key,?V?value)?{

//?我們忽略掉這部分的代碼,只看我們這里最關(guān)心的部分

addEntry(hash,?key,?value,?i);//?這里增加了一個Entry,我們看看代碼

returnnull;

}

voidaddEntry(inthash,?K?key,?V?value,intbucketIndex)?{

Entry?e?=?table[bucketIndex];

table[bucketIndex]?=newEntry(hash,?key,?value,?e);

if(size++?>=?threshold)//?這里是關(guān)鍵,一旦大于等于threshold的數(shù)值

resize(2*?table.length);//?將會引起容量2倍的擴大

}

voidresize(intnewCapacity)?{

Entry[]?oldTable?=?table;

intoldCapacity?=?oldTable.length;

if(oldCapacity?==?MAXIMUM_CAPACITY)?{

threshold?=?Integer.MAX_VALUE;

return;

}

Entry[]?newTable?=newEntry[newCapacity];//?新的容器空間

transfer(newTable);//?復(fù)制數(shù)據(jù)過去

table?=?newTable;

threshold?=?(int)(newCapacity?*?loadFactor);//?重新計算threshold的值

}

好了,我想我們已經(jīng)清楚大部分了。

其中有一點,起始容量必須是2的冪次,這如何保證呢?我們來看看其構(gòu)造方法

publicHashMap(intinitialCapacity,floatloadFactor)?{

//?忽略掉一部分代碼....

//?Find?a?power?of?2?>=?initialCapacity

//?重新查找不比指定數(shù)值大的最大的2的冪次數(shù)

intcapacity?=1;

while(capacity?<?initialCapacity)

capacity?<<=1;

//?其它的初始化代碼?...

}

好了,關(guān)于起始容量和加載因子的探討我們就到這里了。我們應(yīng)該有了一定的了解了。

總結(jié):

相對準確的估算數(shù)據(jù)量,將極大的影響HashMap的性能,因為resize是一個重新分配的過程,耗時應(yīng)該是里面最大的。

加載因子較小,會有更多的空間空閑,我不知道這個0.75是不是一個折中方案。也許0.9也是一個不錯的選擇,特別是那些數(shù)據(jù)量雖然很大,但不是經(jīng)常變化的地方,比如公司人員,城市列表等相對比較固定的數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 5.1、對于HashMap需要掌握以下幾點 Map的創(chuàng)建:HashMap() 往Map中添加鍵值對:即put(Ob...
    rochuan閱讀 875評論 0 0
  • HashMap 是 Java 面試必考的知識點,面試官從這個小知識點就可以了解我們對 Java 基礎(chǔ)的掌握程度。網(wǎng)...
    野狗子嗷嗷嗷閱讀 6,813評論 9 107
  • 前文:HashMap是Java程序員最常用的映射(鍵值對)處理數(shù)據(jù)的容器。隨著JDK版本的更新,1.8相較于1.7...
    是一動不動的friend閱讀 1,320評論 0 1
  • 實際上,HashSet 和 HashMap 之間有很多相似之處,對于 HashSet 而言,系統(tǒng)采用 Hash 算...
    曹振華閱讀 2,562評論 1 37
  • 今天得知,公司老總?cè)谫Y,公司重組,有一號人物進駐,項目即將重啟。 我是回去還是不回? 目前,自己畢業(yè)兩年,過去的工...
    雨季不再回來閱讀 508評論 0 1

友情鏈接更多精彩內(nèi)容