1

假设我有两种类型A,并且B都有一个唯一的id字段,这就是我通常如何实现 equals() 和 hashCode() 方法:

@Override
public boolean equals(Object obj) {
    return obj instanceof ThisType && obj.hashCode() == hashCode();
}

@Override
public int hashCode() {
    return Arrays.hashCode(new Object[] { id });
}

在这种情况下,鉴于A两者B都有一个 1-arg 构造函数来设置各自的id字段,

new A(1).equals(new A(1)) // prints true as expected,
new A(1).equals(new A(2)) // prints false as expected,
new A(1).equals(new B(1)) // prints false as expected.

但是也,

new A(1).hashCode() == new B(1).hashCode() // prints true.

我想知道两个 hashCodes 是否相等是否重要,即使这两个对象不是来自同一类型?hashCode() 可以在 equals() 之外的其他地方使用吗?如果是,目的是什么?


我考虑实现以下两种方法:

@Override
public boolean equals(Object obj) {
    return obj != null && obj.hashCode() == hashCode();
}

@Override
public int hashCode() {
    return Arrays.hashCode(new Object[] { getClass(), id });
}

将类添加到 hashCode 生成将解决这个潜在的问题。你怎么看?有必要吗?

4

6 回答 6

2

对于不同类的对象,相同hashCode()无关紧要。唯一的hashCode()说对象可能是相同的。如果 egHashSet遇到相同的hashCode(),它将测试与 的相等性equals()

于 2013-02-07T10:49:29.617 回答
1

规则很简单:

  • A.equals(B)暗示B.hashcode() == A.hashcode()
  • B.hashcode() != A.hashcode()暗示!A.equals(B)

两者之间应该没有其他关系。如果你使用hashcode()inside equals(),你应该有一个警告。

于 2013-02-07T10:52:37.170 回答
0

Hashcode 绝对不会用在equals; 它由基于称为哈希表的数据结构的集合使用。从正确性的角度来看,两个哈希码彼此相等总是可以的;这被称为哈希冲突,在一般情况下是不可避免的,唯一的后果是性能较弱。

于 2013-02-07T10:50:38.623 回答
0

两个不同的对象(即使是相同类型的对象)具有相同的哈希码并没有错,但是您的第二个变体equals()对我来说看起来很奇怪。只有当您可以保证您的对象只会与相同类型的对象进行比较时,它才会起作用。

于 2013-02-07T10:51:30.700 回答
0
Could hashCode() be used somewhere else than in equals()?

支持此方法是为了哈希表的好处,例如java.util.Hashtable.javadoc提供的哈希表

hashCode 的一般合约是:

  • 每当在 Java 应用程序执行期间对同一个对象多次调用它时,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。
  • 如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要对两个对象中的每一个调用 hashCode 方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
  • 不要求如果两个对象根据equals(java.lang.Object)方法不相等,则对两个对象中的每一个调用 hashCode 方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能
于 2013-02-07T10:52:13.263 回答
0

并不是说,当 A 扩展 B 或 B 扩展 A 时,您的 equals 方法是错误的,因为:

a.equals(b) != b.equals(a)

如果 a 和 b 恰好具有相同的哈希码。

于 2013-02-07T10:54:42.970 回答