条件等于的HashCode

Iva*_*lin 2 java hash hashcode data-structures

我想为以下equals-method生成一个哈希码.

public MyClass class {

  private int a;
  private final String b;

  public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof MyClass)) return false;

        MyClass myClass = (MyClass) o;
        return a == myClass.a || (b == null ? myClass.b == null : b.equals(myClass.b));
  }

  @Override
  public int hashCode() {
      int result = (int) (a^ (a >>> 32));
      result = 31 * result + (b != null ? b.hashCode() : 0);
      return result;
  }

}
Run Code Online (Sandbox Code Playgroud)

问题是equals在两种情况中的一种或两种情况下返回true:o1.a == o2.a或o1.b == o2.b. 在这种情况下,通常的哈希值不同:myClass("a","b")和myClass("a",null)

Jon*_*eet 9

忘记哈希 - 你的平等比较从根本上打破了.

考虑三个值:

foo: a=10, b=0
bar: a=10, b=5
baz: a=20, b=5
Run Code Online (Sandbox Code Playgroud)

现在:

foo.equals(bar) => true because of a
bar.equals(baz) => true because of b
foo.equals(baz) => false because neither a nor b match
Run Code Online (Sandbox Code Playgroud)

这违反了传递性要求Object.equals:

对于任何非空引用值x,yz,如果x.equals(y)返回truey.equals(z)返回true,x.equals(z)则应返回true.

如果你没有传递性,那么hashCode除了返回一个常量(有效但不完全有用)之外,很难找到一个有效的实现.