網(wǎng)上亂七八糟的答案太多了,這里從直觀感受和數(shù)學(xué)方法上對(duì)這塊知識(shí)做了個(gè)整理,數(shù)學(xué)方法基于stackoverflow上的答案,補(bǔ)充了些推導(dǎo)細(xì)節(jié)方便理解。(內(nèi)容比較精簡(jiǎn),后續(xù)有時(shí)間整理下放到個(gè)人博客下)
HashMap是用來(lái)快速查找內(nèi)容的一種數(shù)據(jù)結(jié)構(gòu)。使用n個(gè)桶存儲(chǔ)數(shù)據(jù),數(shù)據(jù)具體存儲(chǔ)在哪個(gè)桶中是由Hash算法決定的,即對(duì)原始內(nèi)容執(zhí)行Hash后得出對(duì)應(yīng)桶的序號(hào)。
然后這種數(shù)據(jù)結(jié)構(gòu)會(huì)遇到一些問(wèn)題,由于內(nèi)存空間有限,所以桶的數(shù)量也是有限制的。當(dāng)桶的數(shù)量較小時(shí)就容易出現(xiàn)較多內(nèi)容放在同一個(gè)桶中的情況。HashMap中使用默認(rèn)的0.75作為桶空間的閾值,如果超過(guò)這個(gè)大小就需要增加桶的數(shù)量,以防止較多內(nèi)容聚集在相同的桶中。
關(guān)于為什么0.75就是經(jīng)常被拿來(lái)當(dāng)做面試問(wèn)題了。首先通過(guò)人腦直觀來(lái)考慮這個(gè)事情,假設(shè)我現(xiàn)在有n個(gè)桶,那么數(shù)據(jù)放到多少我需要增加更多的桶呢。這個(gè)時(shí)候會(huì)出現(xiàn)直觀的數(shù)字0.5,如果桶已經(jīng)裝滿一半了那么之后添加內(nèi)容分配到空桶的概率會(huì)低于分配到有內(nèi)容桶的概率,可想而知從這個(gè)點(diǎn)之后將會(huì)出現(xiàn)越來(lái)越多的內(nèi)容在相同的桶中。從這里來(lái)看這個(gè)0.5是個(gè)非常優(yōu)秀的數(shù)字它是一個(gè)趨勢(shì)的轉(zhuǎn)折點(diǎn)。
但是這個(gè)0.5和負(fù)載因子是不一樣的,這個(gè)0.5我們是指已經(jīng)有一半的桶被占用了,而HashMap中的負(fù)載因子與我們存入的數(shù)據(jù)總數(shù)量相關(guān),并且根據(jù)之前對(duì)這種數(shù)據(jù)結(jié)構(gòu)的了解,數(shù)據(jù)會(huì)存在一定概率出現(xiàn)在一個(gè)桶中,所以當(dāng)一半桶都被占用的時(shí)候我們實(shí)際存儲(chǔ)的數(shù)據(jù)數(shù)量是大于0.5n的。
這里假設(shè)對(duì)于新的內(nèi)容分配到各個(gè)桶的概率是相同的,當(dāng)前內(nèi)容數(shù)據(jù)大小為s。這里使用二項(xiàng)分布的概念,當(dāng)我們進(jìn)行了s次插入操作(實(shí)驗(yàn)),那么序號(hào)0的桶是空桶的概率是多少呢。即:
可以明顯看出來(lái)當(dāng)s增加P(0)是空桶的概率也會(huì)下降,這里用1/2來(lái)計(jì)算這個(gè)分界。即:
然后算下負(fù)載因子f=(s/n)對(duì)n取極限:
為了解決這個(gè)問(wèn)題可以先解決這個(gè)問(wèn)題:
我們得到的結(jié)果就是上面式子的倒數(shù)即e,把log換成ln即得出我們的負(fù)載因子界限值,這個(gè)值約等于0.6931,所以0.75的取值范圍是與這個(gè)界限相近的并且由于基礎(chǔ)是16個(gè)容量空間,使用0.75也不會(huì)算出小數(shù)是一個(gè)不錯(cuò)的值選取。