RSPEC-1206 : overriding hashCode() does not imply equals() should be overridden

Hello.

The rule is (half) wrong.

It says in its title: ‘“equals(Object obj)” and “hashCode()” should be overridden in pairs’, and repeats it at the end: ‘In order to comply with this contract, those methods should be either both inherited, or both overridden.’

However, as clearly stated in the quoted extract from hashCode() javadoc, the contract only says: ‘If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.’, i.e. that if equals() is overridden, then hashCode() must be.

The reason for this contract is that hashCode() is meant to be used as a preliminary hint for example in a hash map for locating where a key would be stored an call equals() on keys
at this location to eventually find it.
If equal keys don’t have the same hash code, the search will be misled and the other key not found.

There is no reason for the other way around, and on the contrary there are reasons to override hashCode() while not overriding equals() - at least the following (and most importantly the last one):

  • To increase bit-spreading in case of using hash collections that would not themselves fiddle with hashCode() result for that purpose (as Doug Lea said: “Many user-defined hashCodes (and some JDK-defined ones too!) are not very good.” (Faster HashMap implementation)).
  • To ensure determinism for hash collections iteration order and toString() (not to pollute logs with irrelevant differences when comparing them for debugging), for data objects for which there are never duplicate instances in the application (typically mutable objects, even though only non-mutable identity-related fields should be used in hashCode()).

Hello Jeff,

Welcome to the community!

Sorry for the late reply.

Thanks for bringing this to our attention. You’re correct—when equals() is overridden, hashCode() should be as well, but not necessarily the other way around. I have created a ticket. You can track its progression here. I appreciate a lot your detailed explanation and feedback.