What are the "worst case" consequences (real world scenarios here), if I have an object (i.e. a bean) which has a solid, meaningful equals()
method, but lacks a complementary hashCode()
method? It seems like most APIs use the equals()
and compareTo()
methods for maintaining collections. I'm wondering when is the hashCode()
most important?

- 203,806
- 29
- 246
- 1,045

- 17,388
- 22
- 92
- 167
-
1This post explains it well: http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java – srchulo Jan 01 '12 at 05:30
3 Answers
The worst-case consequences are that the hash table won't work. For example, lets assume that you've got a simple class like this:
public class StringWrapper {
private String value;
...
public boolean equals(Object other) {
// two objects are equal if their respective values are equal ... using `equals`.
}
// No hashcode override.
}
Here we have a class we have a class does not obey one of the required invariants of the equals/hashcode contract. Specifically, two instances cal be equal, but have different hashcodes.
When you add two different instances of this class to a HashSet, you may end up with both instances in the set ... on different hash chains. You get similar anomalies when removing objects from the set, testing to see if the set contains an object, and so on.
(Note that you may get lucky, and have the two instances end up on the same hash chain despite having different hashcodes. But your luck could change when some other unrelated object is added to the hash table, causing it to automatically resize. The resize is liable to cause entries with different hashcodes to be redistributed to different hash chains.)
So I'm wondering... when is the hashcode most important ?
It is always important.
Or to put it another way, it is only unimportant when you know with 100% certainty that instances of the class are never ever going to be used in hash tables. (And I don't know how you can know that, unless you delete all copies of the class. And that renders the whole question moot!)
UPDATE
@supercat mentioned the case where you can't write a decent hashcode.
If there is some good reason you can't write a half-decent hashcode()
method, I'd advocate overriding it to throw UnsupportedOperationException
or some such. That way you get a fast-fail if someone tries to put an instance into a hash table ... rather than a mysterious performance black-hole. (I would NOT recommend returning a constant hashcode.)
There is a related scenario where you might do this: when the object is inherently mutable, and you want to avoid the badness that happens if you mutate a hash key so that its hashcode changes.

- 698,415
- 94
- 811
- 1,216
-
-
Even if one doesn't expect an object to ever be used in a hash-table, there's no reason not to override hashCode when overriding equals. If it's impossible to define a *meaningful* hashcode value, override the method to return a constant; that's easy to do, and will ensure that if the object is used in a hash table it will work *correctly* (performance will be bad with large hash tables, but having slow performance if the object is used in a hash table is probably better than having weird failures). – supercat Mar 13 '13 at 16:46
-
@supercat - if there is some good reason you can't write a half-decent `hashcode()` method, I'd advocate overriding it to throw `UnsupportedOperationException` or some such. – Stephen C Mar 14 '13 at 02:36
-
@StephenC: If someone has a `List
` containing e.g. 12 items and wants to count the number of *distinct* items, the fact that `Foo` is not amenable to hashing should not cause such an operation to fail. If `Foo` overrides `hashCode` to always return 0xF00, a method `CountDistinct – supercat Mar 14 '13 at 15:38` which uses a `HashSet ` to count the number of distinct elements might run for hours if given a set containing 1,000,000 items, but if given a set of 12 items it would run almost as fast as if the hashcode function returned something useful.
If you're going to be concerned with either of these, you really, really should (need) to implement / override both. See Why do I need to override the equals and hashCode methods in Java? for specifics, including what can happen if these aren't implemented with proper, related implementations.
Additionally, from another answer there:
You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.
from Effective Java, by Joshua Bloch
This method returns the hash code value for the object on which this method is invoked. This method returns the hash code value as an integer and is supported for the benefit of hashing based collection classes such as Hashtable, HashMap, HashSet etc. This method must be overridden in every class that overrides the equals method.

- 123,721
- 27
- 225
- 246

- 18,414
- 7
- 41
- 58
-
2I didn't downvote, but your Answer clearly doesn't answer the question that was asked. He wants to know *why* you have to override the method and (more specifically) what happens if you don't do this. – Stephen C Jan 01 '12 at 06:18
-
I didnt downvote either, but.... this doesn't answer the question --- the question is ?WHY? the hashcode was important. – jayunit100 Jan 03 '12 at 01:48