编辑: 此问题与按位运算符无关,无法使用Why are XOR often used in java hashCode() but another bitwise operators are used rarely?
回答我已经看到了对象哈希计算的不同方法:
class A {
public B b;
public C c;
@Override
public boolean equals();
@Override
public int hashCode() {
return c.hashCode() ^ b.hashCode(); //XOR
return c.hashCode() + prime * b.hashCode(); // SUM
return Objects.hash(b,c); // LIB
}
}
似乎LIB方法使用SUM,但为什么它比XOR更好?
尽管这个例子是用Java编写的,但这个问题更多的是关于数学和概率。</ p>
答案 0 :(得分:5)
SUM确保您使用散列码的所有位来扩展散列(在此,int的32位),并且不对此实现子hashcode()实现。
如果B和C的哈希码具有相同的属性,则XOR只具有相同的属性,否则它将仅使用B和C哈希码中“有用”位数的最小值,这可能导致更差的分布,并且更频繁的碰撞。如果B和C是非常小的整数,那么很容易看出问题,你只会使用前几位(因为int.hashcode()是身份函数)。
答案 1 :(得分:0)
这是因为sum
提供的分发比xor
更好。
例如,如果int
a
和b
的值介于0和7之间(000
和111
二进制),则结果为{{1这两个参数总是在0到7之间(因为xor
只会改变3位)。现在,当你进行乘法和xor
时,你会有更好的分布,因为这些值不会在0和7范围内。
答案 2 :(得分:-1)
答案是(一如既往):&#34; 取决于。&#34;这取决于你的班级。
例如,如果您考虑
class X {
T a, b;
X(T _a, _b) { a = _a; b = _b }
}
你不会使用像+
,*
或^
这样的对称运算符(想象T
是int
,而你正在哈希{{1}显然哈希代码应该是不同的。所以三个&#34;解决方案中的第一个&#34;(xor哈希值)会很糟糕。
如果X(1,2)
是一个复杂类型,第三个解决方案(X(2,1)
)也可能不好,因为只考虑引用(相等的对象可以返回不同的哈希码)。