我们用 eclipse 自动生成 hashCode() 方法时一般会得到类似如下的代码:
...
final int PRIME = 31;
int result = 1;
result = PRIME * result + a;
result = PRIME * result + ((b == null) ? 0 : b.hashCode());
result = PRIME * result + Float.floatToIntBits(c);
...
我的疑问是这里的 31 是如何得来的?为什么下面每步都要将上面的结果乘以 31 再加?这个算法如何得来?
...
final int PRIME = 31;
int result = 1;
result = PRIME * result + a;
result = PRIME * result + ((b == null) ? 0 : b.hashCode());
result = PRIME * result + Float.floatToIntBits(c);
...
我的疑问是这里的 31 是如何得来的?为什么下面每步都要将上面的结果乘以 31 再加?这个算法如何得来?
result = result + a;
result = result + ((b == null) ? 0 : b.hashCode());
result = result + Float.floatToIntBits(c);
exactly! public static void main(String... args) throws Exception {
String[] names = {"332", "a7"};
for (String s : names)
System.out.println(hash(s) + ":\t" + s);
}
private static int hash(String s) {
int h = 0;
int len = s.length();
for (int i = 0; i < len; i++)
h = 31 * h + s.charAt(i);
return h;
} gives output: 50642: 332
3062: a7
But if we replace 31 with 1, we get:
152: 332
152: a7
因此,如何在生成HashCode时尽量防止碰撞是很重要的.在这个基础上通过测试以及部分理论证明,发现使用一个质数作为生成HashCode的因子时,往往能够得到分布相对均匀的映射区间.从而尽可能的避免在某一个数值区间内发生大量的碰撞.
至于为什么选31,因为这是一个经验值,这样可以获取效率与空间的相对优值.(实际上计算hashcode的方法很多,使用31只能说是一个经典值而已,相当多的语言都不这样算的.)我知道的就这么多了,也是以前在研究HashMap时查资料看到的.其实你可以上网搜搜,其实你问的也是经典问题了,可以说是有定论的.