public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
該函數是我看的函數接口源碼,爲什麼要使用31這個數呢?
其實上面的實現也可以總結成數數裏面下面這樣的公式:
s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]
原因如下:
A.31是一個素數,素數作用就是如果我用一個數字來乘以這個素數,那麼最終的出來的結果只能被素數本身和被乘數還有1來整除!。(減少衝突)
B.31可以 由i*31== (i<<5)-1來表示,現在很多虛擬機裏面都有做相關優化.(提高算法效率)
C.選擇係數的時候要選擇儘量大的係數。因爲如果計算出來的hash地址越大,所謂的“衝突”就越少,查找起來效率也會提高。(減少衝突)
D.並且31只佔用5bits,相乘造成數據溢出的概率較小。