Re: Java HashSet Problem
pjvleeuwen@gmail.com wrote:
....
Person overwrites equals(Object) in a correct way, but does not
overwrite the hashCode() method.
Almost invariably, equals cannot be overridden "in a correct way"
without also overriding hashCode().
....
If I am reading this correctly, then the equals method is only
evaluated when the hashes of the two objects are equals. Since I did
not overwrite Object#hashCode() HashSet#contains(Object) returns false
in the above scenario.
....
Correct, but to turn this into a problem in HashSet, rather than in yoru
class, you need to ignore a critical piece of documentation.
HashSet, like all Java classes, is limited to operating on objects whose
class extends, directly or indirectly, java.lang.Object. Therefore, its
implementation can assume that the objects in the set follow the rules
stated in the java.lang.Object documentation.
From the documentation for equals: "Note that it is generally necessary
to override the hashCode method whenever this method is overridden, so
as to maintain the general contract for the hashCode method, which
states that equal objects must have equal hash codes.". This makes
overriding equals without maintaining the hashCode contract incorrect.
From the documentation for hashCode: "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."
The Java APIs are full of method implementations that depend on methods
in other classes behaving according to some aspect of the documented
contract for one of the class's superclasses or interfaces. Generally,
those dependencies are only documented through the type of the
reference. Otherwise, the documentation would be impossibly cluttered
with some phrase like "... provided parameter x of type X conforms to
the X contract."
Requiring an Object reference means that the Object contract applies,
not that there is no contract.
Patricia