I was trying to debug my code which uses a HashSet
and searching through the SO, I found out that I needed to override the hashCode
method as well. The strange part is, checking the related API, I did not see any part in it mentioning about the hashCode
method. Quoting the definition of the add
method of HashSet
as seen in the API:
public boolean add(E e)
Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.
Now in the quotation above, I don't see anywhere that mentions about the hashCode
method. Shouldn't the correct statement have been like:
... if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)) AND if this set contains no element e2 such that (e==null ? e2==null : e.hashCode() == e2.hashCode()).
Now if you say that: "If o1.equals(o2)
returns true, o1.hashCode()
== o2.hashCode()
MUST evaluate to true as well.", then I would ask three questions:
Where is that fact specified? (in general, or in the API)
Even if that fact is specified somewhere, where in the API it is specified that
HashSet
makes use of thehashCode
method?If that fact is indeed correct, why isn't the compiler enforces overriding the
hashCode
method, whenever theequals
method is overridden?
HashSet
documentation does not, technically, need to specify thathashCode
: The contract that equality implies equal hash codes is a general contract onObject#hashCode
, so it applies to all objects. All code is within its rights to usehashCode
and assume that contract holds. That said, given that many beginners do not read that part of the documentation, and that many other resources felt the need to mention it explicitly, it certainly would be more useful if the JavaDoc highlighted this aspect.