I have a hash-based collection of objects, such as HashSet
or HashMap
. What issues can I run into when the implementation of hashCode()
http://community.jboss.org/wiki/EqualsandHashCode
If you add an object to a hash-based collection, then mutate its state so as to change its hashcode (and by implication probably the behaviour in .equals()
calls), you may see effects including but not limited to:
This is surely not what you want. So, I recommend making the hashcode only out of immutable fields. This is usually done by making the fields final
and setting their values in the constructor.
If the hash code of the same object changes over time, the results are basically unpredictable. Hash collections use the hash code to assign objects to buckets -- if your hash code suddenly changes, the collection obviously doesn't know, so it can fail to find an existing object because it hashes to a different bucket now.
Returning an object's ID by itself isn't bad, but if many of them have id=0 as you mentioned, it will reduce the performance of the hash table: all objects with the same hash code go into the same bucket, so your hash table is now no better than a linear list.
Update: Theoretically, your hash code can change as long as nobody else is aware of it -- this implies exactly what @bestsss mentioned in his comment, which is to remove your object from any collections that may be holding it and insert it again once the hash code has changed. In practice, a better alternative is to generate your hash code from the actual content fields of your object rather than relying on the database ID.
Don’t change hashcode of elements in hash based collection after put.
Many programmers fall into the pitfall. You could think hashcode is kind of address in collection, so you couldn’t change address of an element after it’s put in the collection.
The Javadoc spefically says that the built-in Collections don't support this. So don't do it.