散列复合对象

时间:2013-06-25 12:16:19

标签: java hash

编辑: 此问题与按位运算符无关,无法使用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>

3 个答案:

答案 0 :(得分:5)

SUM确保您使用散列码的所有位来扩展散列(在此,int的32位),并且不对此实现子hashcode()实现。

如果B和C的哈希码具有相同的属性,则XOR只具有相同的属性,否则它将仅使用B和C哈希码中“有用”位数的最小值,这可能导致更差的分布,并且更频繁的碰撞。如果B和C是非常小的整数,那么很容易看出问题,你只会使用前几位(因为int.hashcode()是身份函数)。

答案 1 :(得分:0)

这是因为sum提供的分发比xor更好。

例如,如果int ab的值介于0和7之间(000111二进制),则结果为{{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 }
}

你不会使用像+*^这样的对称运算符(想象Tint,而你正在哈希{{1}显然哈希代码应该是不同的。所以三个&#34;解决方案中的第一个&#34;(xor哈希值)会很糟糕。

如果X(1,2)是一个复杂类型,第三个解决方案(X(2,1))也可能不好,因为只考虑引用(相等的对象可以返回不同的哈希码)。