散列复合对象

Bas*_*evs 11 java hash

编辑: 这个问题不是关于按位运算符,无法回答为什么XOR经常在java hashCode()中使用,但很少使用其他按位运算符?

我已经看到了对象的哈希计算的不同方法:

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
  }
}
Run Code Online (Sandbox Code Playgroud)

似乎LIB方法使用SUM,但为什么它比XOR更好?

即使示例是Java,这个问题更多的是关于数学和概率.

C4s*_*tor 5

SUM确保您使用散列码的所有位来扩展散列(在此,int的32位),并且不做出关于子hashcode()实现的假设.

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