為什么HashMap的負(fù)載因子是0.75

網(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的桶是空桶的概率是多少呢。即:

P(0) = \tbinom{s}{0}(\frac{1}{n})^0(1-\frac{1}{n})^s

可以明顯看出來(lái)當(dāng)s增加P(0)是空桶的概率也會(huì)下降,這里用1/2來(lái)計(jì)算這個(gè)分界。即:

\begin{array}{c} (1- \frac{1}{n})^s &\ge& \frac{1}{2} \\ (\frac{n}{n-1})^s & \le & 2 \\ s & \le & \frac{log(2)}{log(\frac{n}{n - 1})}\end{array}

然后算下負(fù)載因子f=(s/n)對(duì)n取極限:

f \le \lim_{n->\infty}{\frac{log(2)}{log((\frac{n}{n-1})^n)}}

為了解決這個(gè)問(wèn)題可以先解決這個(gè)問(wèn)題

\lim_{n->\infty}(1-\frac{1}{n})^n = \frac{1}{e}

我們得到的結(jié)果就是上面式子的倒數(shù)即e,把log換成ln即得出我們的負(fù)載因子界限值\ln2,這個(gè)值約等于0.6931,所以0.75的取值范圍是與這個(gè)界限相近的并且由于基礎(chǔ)是16個(gè)容量空間,使用0.75也不會(huì)算出小數(shù)是一個(gè)不錯(cuò)的值選取。

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

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