Object.hashCode()的默认行为是返回对象的“地址”,以便当且仅当a == b时a.hashCode()== b.hashCode()。如果超类已经定义了hashCode(),我怎样才能在用户定义的类中获得这种行为?例如:
class A {
public int hashCode() {
return 0;
}
}
class B extends A {
public int hashCode() {
// Now I want to return a unique hashcode for each object.
// In pythonic terms, it'd look something like:
return Object.hashCode(this);
}
}
想法?
答案 0 :(得分:26)
System.identityHashCode(Object)提供了这种行为。
你会写这个:
class B extends A {
public int hashCode() {
return System.identityHashCode(this);
}
}
如果两个对象相同,请检查equals-method,它只返回true。否则会破坏equals和hashCode所描述的行为。 (为了正确,如果为两个对象获得不同的哈希码,则equals-method必须返回false。)提供符合给定hashCode()的equals()实现 - 方法:
public boolean equals(Object other){
return this == other;
}
答案 1 :(得分:9)
使用System.identityHashCode()
。这是IdentityHashMap
使用的内容。
你应该非常警惕用这个覆盖现有的hashCode()
,因为你可能会破坏hashCode合同,因为这两个对象:
如果a.equals(b)则a.hashCode()必须等于b.hashCode()
您可以通过覆盖现有行为来解决此问题,或者您也可能需要覆盖equals()。
答案 2 :(得分:1)
正如Mnementh所说的那样,我只想指出hashCode()返回0(或任何常量值)是有效的(虽然是跛脚)。 hashCode()只有在!a.equals(b)的情况下才能(并且应该)为a和b返回不同的值 所以例如你有
class A {
public int hashCode() {
return 0;
}
public boolean equals(Object o) {
return o instanceof A; // all objects are equal
}
}
class B extends A {
public int hashCode() {
return System.identityHashCode(this);
}
public boolean equals(Object o) {
return this.hashCode().equals(o.hashCode());
}
}
现在您创建两个对象:
A a = new A();
A b = new B();
突然a.equals(b),但是!b.equals(a)。当然在更现实的生活中,A中的equals()会更复杂,但问题仍然存在。要摆脱这个问题,你想要总是打电话
if (super.equals(o)) return true;
在新的equals()的开头。
由于重写hashCode()严格依赖于重写equals(),因此您需要确保任何两个给定对象的super.equals()返回true,新的hashCode()将返回super.hashCode()。