每Java文档中,哈希代码的String对象被计算为:
String
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 使用int算术,其中s[i]是 我 字符串的个字符,n是字符串的长度,以及^表示取幂。
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用int算术,其中s[i]是 我 字符串的个字符,n是字符串的长度,以及^表示取幂。
int
s[i]
n
^
为什么将31用作乘数?
我知道乘数应该是一个相对较大的素数。那么为什么不29或37甚至97?
根据约书亚·布洛赫(Joshua Bloch)的《有效的Java》(这本书不值得推荐,由于对stackoverflow的不断提及,我买了这本书):
选择值31是因为它是奇数质数。如果是偶数且乘法运算溢出,则信息将丢失,因为乘以2等于移位。使用质数的优势尚不清楚,但这是传统的。31的一个不错的特性是乘法可以用移位和减法来代替,以获得更好的性能:31 * i == (i << 5) - i。现代VM自动执行这种优化。
31 * i == (i << 5) - i
(摘自第3章第9项:当您覆盖等号时,请始终覆盖哈希码,第48页)