两个hashCodes是否相等是否重要,即使这两个对象不是来自同一类型?

时间:2013-02-07 10:46:49

标签: java unique equals hashcode

假设我有两种类型AB,它们都有一个唯一的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 });
}

在这种情况下,假设AB都有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生成将解决此潜在问题。你怎么看?有必要吗?

6 个答案:

答案 0 :(得分:2)

对于不同类的对象,相同的hashCode()并不重要。 hashCode()仅表示对象可能相同。如果是HashSet遇到相同的hashCode(),它会测试与equals()的平等。

答案 1 :(得分:1)

规则很简单:

  • A.equals(B)隐含B.hashcode() == A.hashcode()
  • B.hashcode() != A.hashcode()隐含!A.equals(B)

两者之间不应该存在其他关系。如果您在hashcode()内使用equals(),则应该收到警告。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

两个不同的对象(即使是同一类型)没有错误,但是你的equals()的第二个变体看起来很奇怪。仅当您可以保证仅将对象与相同类型的对象进行比较时,它才会起作用。

答案 4 :(得分:0)

Could hashCode() be used somewhere else than in equals()?

此方法受哈希表的支持,例如来自javadocjava.util.Hashtable.提供的哈希表

另外

hashCode的一般合约是:

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

答案 5 :(得分:0)

不是这样,当A扩展B或B扩展A时,那么你的equals方法是错误的,因为:

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

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