假设我有两种类型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生成将解决此潜在问题。你怎么看?有必要吗?
答案 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()?
此方法受哈希表的支持,例如来自javadoc的java.util.Hashtable.
提供的哈希表
另外
hashCode的一般合约是:
equals(java.lang.Object)
方法两个对象不相等,则不需要在两个对象中的每一个上调用hashCode方法必须产生不同的整数结果。但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。答案 5 :(得分:0)
不是这样,当A扩展B或B扩展A时,那么你的equals方法是错误的,因为:
a.equals(b) != b.equals(a)
如果a和b恰好具有相同的哈希码。