I have a HashSet<Foo>
.
I have an object that is
Still if I call hashSet.contains(fooInstance)
it returns false
.
Where it gets really weird is that the following line returns true
:
new ArrayList<Foo>(hashSet).contains(fooInstance)
Sadly it turned out harder than expected to find out where exactly is the difference of the .contains()
implementation.
But I thought I would be safe, since .equals()
and .hashCode()
work fine.
The most likely reason is that the hashCode
of Foo
is not stable and that the return value of hashCode()
of the Foo
instance changed after it was added to the HashSet
. Ideally, you would only ever add immutable objects to a HashSet
.
For performance reasons the HashSet
stores the calculated hashCode
in its entry, so that it doesn't need to re-calculate it for each get
. So if the object changes while inside the HashSet
, this won't be realized and your object will effectively be "lost" in the HashSet
(you can still get it, by iterating over all elements, which is essentially what copying into an ArrayList
does).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With