The problem is that the hash of the object R can change . This is a breach of contract that the hashCode() method must obey.
To understand why this matters, you need to understand how the hash table works. Java HashSet has in its heart an array of record lists. When you put an object in a hash table, it first computes the hash code of the object. Then it reduces the hash code to an index in the array, computing
index = hashcode % array.length
He then looks for the chain starting with array[index] , and if the object is not in the list, he adds it.
And to check if the HashSet contains an object, it performs the same calculations and looks for the same hash chain.
However, if you are doing something for the object so that its hash code changes while it is in the table, then the above algorithm (usually) looks for the object in another chain in the chain to which it was originally added. And, of course, it will not find.
The end result is that the HashSet will behave abnormally if the hashcode contract is broken for any object while the object is a member of the collection.
Here is what Java javadoc says (see java.jang.Object # hashcode ()):
"General hashCode contract:
Whenever it is called on the same object more than once during the execution of a Java application, the hashCode method must consistently return the same integer if the information used in equal comparisons with the object does not change. This integer should not remain consistent with one execution of the application on another execution of the same application.
...
"No information provided ..." the clause puzzles me. I think this only works if there is a rule that you should not change the hash codes of the object when they are in the hash table. Unfortunately, this rule is not specified in any of the places that you expect to find. Error in the documentation?
Perhaps we should name the requirement not to change the hash codes "verbal agreement"? :-)
source share