Short answer
The map places the entry in the bucket determined by the key's hash at insertion time, so mutating a field that participates in hashCode moves the object's logical bucket while it physically stays put.
Explanation
After that, contains and get compute the new hash, look in the wrong bucket, and report the element missing even though it's still in the map, effectively leaking it. The rule is to use immutable keys or at least never mutate key fields while the object is in a hash structure; records make excellent keys precisely because they're immutable.
Common mistakes
- Mutating a key's hash fields after inserting it.
- Expecting contains() to still find the moved key.