哈希码是什么?

3
int value = 5381;

for (int i = 0; i < item.length(); i++) {
  value = value * 33 + item.charAt(i);
}

value &= 0x7fffffff;
value %= size;

这是Bernstein的哈希码。除了最后两行之外,我都懂。它们做什么?它们还会导致Java编译器出错,因此它们显然不是有效的代码。如果不使用这种方式,另外如何表示呢?
其实我不太在意它们做什么,只要它们能工作就好啦 :P

1
如果你遇到了一个你不认识的Java运算符,只需在Google上输入“Java运算符”即可。 - Oliver Charlesworth
1
对我来说编译(和运行)很好。当然,你必须将“item”定义为字符串,将“size”定义为整数。 “item”是您要哈希的字符串,“size”是您将使用生成的“value”索引的哈希表的大小。 - Hot Licks
2个回答

7
< p > 位运算符&的目的是将所有值移动到正整数范围内。这比简单的绝对值操作更好地保留了前面操作所创建的均匀分布。此外,如@yshavit在评论中指出的一样,去掉负号的一般原因是< code > value 可能最终会用作某种索引。

取模运算符%的目的是使哈希码适合有限大小的空间。


2
尝试一下:System.out.println(-10&0x7FFFFFFF); - The111
2
@user 你应该在某个时候仔细研究一下。在你的编程生涯中,二进制补码将会再次出现。 - yshavit
1
此外,@The111,关于使整数非负(而不是正数)的目的,可能不仅仅是为了使模函数更加均匀分布。模函数取其第一个参数的符号(jls [15.17.3](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3)),如果`value`将用作数组或列表的索引,则重要的是它不是负数。 - yshavit
1
@yshavit 很有道理,但我的意思是使用这种去除符号的方法可能比简单的绝对值更能保持均匀分布。我会编辑以澄清并包括您的观点。谢谢。 - The111
2
另外,Math.abs(Integer.MIN_VALUE) 仍然是负数。 ;) - Louis Wasserman
显示剩余7条评论

3

& 是按位与运算符,% 是取模运算符。

&=%= 显然是这些操作和 = 的简写方式。


它们不是“=”的速记形式,“x (op) y”实际上是“x = x (op) y”的速记形式(如果您使用自定义数据类型,至少应该是这样)。 - Cole Tobin
嗯,什么?这意味着 int x=1; x + 1;int x=1; x=x+1; 的速记方式,这绝对是不正确的。 - yshavit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接