三、String的hashCode()深刻分析
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
推導出的公式以下:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
舉個例子推導計算一下:
假設 n=3 i=0 -> h = 31 * 0 + val[0] i=1 -> h = 31 * (31 * 0 + val[0]) + val[1] i=2 -> h = 31 * (31 * (31 * 0 + val[0]) + val[1]) + val[2] h = 31*31*31*0 + 31*31*val[0] + 31*val[1] + val[2] h = 31^(n-1)*val[0] + 31^(n-2)*val[1] + val[2]
3.一、爲何使用31做爲計算的因子呢?
- 選擇質數做爲乘子,會大大下降hash衝突的機率。質數的值越大,hash衝突率越低
- 31參與乘法運算,能夠被 JVM 優化,
31 * i = (i << 5) - i
- 使用 101 計算 hash code 容易致使整型溢出,致使計算精度丟失