【问题标题】:HashCode for conditional equals条件等于的 HashCode
【发布时间】:2014-08-13 14:46:17
【问题描述】:

我想为以下等号方法生成一个哈希码。

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;
  }

}

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

【问题讨论】:

  • 解决方案:要么对哈希数据结构使用复合键,要么对每个字段分别使用不同的哈希数据结构。

标签: java data-structures hash hashcode


【解决方案1】:

忘记哈希 - 你的相等比较从根本上被破坏了。

考虑三个值:

foo: a=10, b=0
bar: a=10, b=5
baz: a=20, b=5

现在:

foo.equals(bar) => true because of a
bar.equals(baz) => true because of b
foo.equals(baz) => false because neither a nor b match

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

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

如果您没有传递性,那么除了返回一个常量(这是有效的,但并不完全有用)之外,很难想出一个有效的hashCode 实现。

【讨论】:

    猜你喜欢
    • 2010-09-16
    • 2022-11-16
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 2011-08-14
    • 2014-02-09
    • 2021-12-17
    相关资源
    最近更新 更多