Java HashMap containsKey
The following statement breaks your Map:
p.setName("charlie");
It causes the key referenced by the variable p
to no longer be positioned in the bin that matches its hashCode()
, since you are changing its hashCode()
.
You should never change the state of a key that is already in the Map if that change affects the result of hashCode()
or equals()
.
p.setName("charlie");
System.out.println("3. " + map.containsKey(p));
Returns false
since a Person
instance whose name is "charlie" is not mapped to the same bin as a Person
instance whose name is "alice". Therefore containsKey()
searches for p
in the bin matching the name "charlie", and doesn't find it there.
Person p2 = person("alice", 3);
System.out.println("4. " + map.containsKey(p2));
Returns false
since p2
is not equal to p
(they have different names).
Person p3 = person("charlie", 3);
System.out.println("5. " + map.containsKey(p3));
Returns false
since the key p
is located in the bin that matches the name "alice", even though its current name is "charlie", so containsKey()
searches for it in the wrong bin, and doesn't find it.
You're modifying the object after adding it as a key in the HashMap
, in a way that changes the hash code. That's like giving someone your contact details, moving house, and then still expecting them to be able to find you.
When you add a key to the map, it stores the hash code. When you try to find a key, the map asks for the hash code of the key you're trying to find, and efficiently finds any entries with the same stored hash code. As the "new" hash code doesn't match the "old" hash code, it can't find any candidates to check with equals
.
Basically, you shouldn't modify anything that affects the hash code or equality after using the object as a key in the map.