在Java中,哈希代码用于String对象被计算为
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用int算术,其中s[i]是字符串的i第四个字符,是字符串n的长度,并^指示指数。
为什么31被用作乘数?
我知道乘数应该是一个相对较大的素数。那么为什么不是29,或37,甚至97?
通过相乘,位向左移动。这使用了更多的散列码可用空间,减少了冲突。
通过不使用2的幂,低位,最右边的位也被填充,以与下一个进入散列的数据混合。
表达式n * 31相当于(n << 5) - n。
(大部分)旧的处理器上,乘以31可能会相对便宜。例如在ARM上,它只是一个指令:
RSB r1, r0, r0, ASL #5 ; r1 := - r0 + (r0<<5)
大多数其他处理器将需要单独的移位和减法指令。但是,如果你的乘数很慢,这仍然是一个胜利。现代的处理器往往有快速的乘法器,所以它没有太大的区别,只要32是正确的一面。
这不是一个很好的哈希算法,但它比1.0代码更好,更好(并且比1.0版本好得多)。