Java: Why you should always override hashCode when overriding equals
What could happen if I only override equals?
- Suppose you only override
equalsbut nothashCode - This means that
hashCodeis inherited fromObject Object.hashCodealways tries to return different hash codes for different objects (regardless if they areequalor not)- This means that you may end up with different hash codes for two objects that you consider to be
equal - This in turn causes these two equal objects to end up in different buckets in hash based collections such as
HashSet - This causes such collections to break
Let's illustrate with an example:
class IntBox {
int i;
IntBox(int i) { this.i = i; }
// equals other IntBoxes that store the same int value.
@Override
public boolean equals(Object o) {
IntBox other = (IntBox) o;
return this.i == other.i;
}
}
class Main {
public static void main(String[] args) {
Set<IntBox> intBoxes = new HashSet<>();
intBoxes.add(new IntBox(0));
boolean found = intBoxes.contains(new IntBox(0));
// found == false
}
}
What could happen if I only override hashCode?
This will not break the code as above, but may degrade performance.
- Suppose you only override
hashCodebut notequals - This means that you may return the same hash code for two non-equal objects
Object.hashCodemight do so too, but it does an as good job as possible to avoid it
- This in turn means that two non-equal objects end up in the same bucket in a hash based collection such as
HashSet - This degrades performance since objects are not distributed as evenly as possible among the buckets
Put differently: If you don't override equals any two objects will be considered non-equal. Since Object.hashCode ensures that all objects are distributed as evenly as possible in a hash based collection Object.hashCode is optimal, and overriding it with anything else will worsen the performance.
Comments
Be the first to comment!