I knew better. Yet, I decided to be lazy and not override hashCode() even though I was overriding equals() in my class. Then, I put them in sets. Then, I tried to do set operations, and it was all over.
Problems first arose when I was trying to get the difference and intersection of two HashSets using removeAll and retainAll. The one set had two elements, and the other set one element. The one element was equal to, but not identical to, one of the elements in the first set. However, first.retainAll(second) rendered first to an empty set, and first.removeAll(second) would leave first untouched. It was almost as if removeAll and retainAll were using identity rather than equality.
However, then I found a post (http://www.java-forums.org/advanced-java/12812-does-retainall-use-equals.html) where Norm set me and the poster straight. We had both forgotten to implement hashCode().
For a HashSet to determine if an element exists inside of it, it uses hashCode to look in a bucket. If you implement hashCode incorrectly, then you could have equal elements with different hashCodes, and when the HashSet attempts to find your object, it will be looking in the wrong bucket. It will never find it.
You will similarly break your HashMap objects if your keys have improperly implemented hashCode() methods.
So, if you override equals(), make sure your hashCode() method will return the same value for any two equal instances, or else you’re asking for trouble!
Tags: java