String 類的方法 -- hashCode()實(shí)現(xiàn)的常量系數(shù) 為什么是31

先上源碼:

/**

* Returns a hash code for this string. The hash code for a

* {@code String} object is computed as

* <blockquote><pre>* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

* </pre></blockquote> * using {@code int} arithmetic, where {@code s[i]} is the

* <i>i</i>th character of the string, {@code n} is the length of

* the string, and {@code ^} indicates exponentiation.

* (The hash value of the empty string is zero.)

*

* @return? a hash code value for this object.

*/

public int hashCode() {

int h =hash;

if (h ==0 &&value.length >0) {

char val[] =value;

for (int i =0; i

h =31 * h + val[i];

}

hash = h;

}

return h;

}

相信很多朋友跟我一樣,在查看String 類中hashCode() 方法具體實(shí)現(xiàn)的時(shí)候,會(huì)有個(gè)一疑問,為什么會(huì)有個(gè)常量系數(shù) 31,這個(gè)31是什么,怎么來的?有什么具體的含義;然后就各種查;

我也是簡(jiǎn)單的查了一下,網(wǎng)上的對(duì)這個(gè)解讀的資料還是蠻多的,很輕松的找到可答案;

整理了一下,主要是有一下幾種原因:

1、31是素?cái)?shù),素?cái)?shù)是什么?素?cái)?shù)也是質(zhì)數(shù),除了1和它本身以外,沒有其他因數(shù)。所以不能被其他自然數(shù)整除

2、在存儲(chǔ)數(shù)據(jù)計(jì)算hash地址的時(shí)候,我們希望相同的hash地址越少越好,也就是所謂的“沖突”,因?yàn)橄嗤膆ash地址的數(shù)據(jù)越多,生成的hash鏈表就越長(zhǎng),查找數(shù)據(jù)遍歷的時(shí)間就越長(zhǎng),從而降低了查詢效率。所以在選擇系數(shù)的時(shí)候,我們希望這個(gè)系數(shù)越大越好(hash地址越大,沖突的概率越小,查詢效率就高),但是相乘最好不要溢出(系數(shù)越大,越容易造成數(shù)據(jù)溢出,溢出的話,會(huì)造成數(shù)據(jù)的丟失)。而 31= 11111【二進(jìn)制】,只占5bits。

3、我們都知道,計(jì)算機(jī)的乘法涉及到移位計(jì)算,一個(gè)數(shù)*2直接將這位數(shù)往左移一位即可,31*i = 2^5 * i - i, 相當(dāng)于 i 向 左移動(dòng)5位,再減 i,這樣就轉(zhuǎn)化成移位和減法結(jié)合的計(jì)算,比直接相乘的速度更快。也算是對(duì)算法的一種優(yōu)化

綜合以上幾個(gè)原因,選擇了31這個(gè)系數(shù)。

?著作權(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ù)。

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

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