Reputation: 569
The default behavior of Object.hashCode() is to return essentially the "address" of the object so that a.hashCode() == b.hashCode() if and only if a == b. How can I get this behavior in a user-defined class if a superclass already defines hashCode()? For instance:
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);
}
}
Ideas?
Upvotes: 11
Views: 2491
Reputation: 51311
System.identityHashCode(Object) provides this behaviour.
You would write this:
class B extends A {
public int hashCode() {
return System.identityHashCode(this);
}
}
Please check the equals-method, that it only returns true, if the two objects are the same. Otherwise it would break behaviour described for equals and hashCode. (To be correct, the equals-method has to return false, if you get different hashcodes for two objects.) To provide an implementation of equals() that comply with the given hashCode()-method:
public boolean equals(Object other){
return this == other;
}
Upvotes: 26
Reputation: 165
As Mnementh said it all, I'd just like to point out that hashCode() returning 0 (or any constant value) is valid (while lame). hashCode() can (and should) return different values for a and b only if !a.equals(b).
So for example you have
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());
}
}
Now you create two objects:
A a = new A();
A b = new B();
And suddenly a.equals(b), but !b.equals(a). Of course in more real life the equals() in A will be more sophisticated, but the problem still persist. To get rid of this problem you want to always call
if (super.equals(o)) return true;
at the beginning of new equals().
And since overriding hashCode() is strictly tied to overriding equals(), you want to make sure that everywhere super.equals() returned true for any two given objects, new hashCode() will return super.hashCode().
Upvotes: 1
Reputation: 625097
Use System.identityHashCode()
. This is what IdentityHashMap
uses.
You should be extremely wary of overriding an existing hashCode()
with this though because you might break the hashCode contract, being that two objects that:
if a.equals(b) then a.hashCode() must equal b.hashCode()
You might break this by overriding the existing behaviour or you might need to override equals() too.
Upvotes: 9