Card 06/ 08
All 8 cards
GotchaDifficulty: Advanced1 min
Why Changing a Key After Putting It In Loses the Entry
Both methods are overridden correctly, from the same field. The entry goes in, one field on the key object is updated, and the entry is gone.
Order key = new Order("AB-1");
Map<Order, String> map = new HashMap<>();
map.put(key, "paid");
key.reference = "AB-2";
System.out.println(map.get(key));
System.out.println(map.get(new Order("AB-1")));
System.out.println(map.size());null
null
1The bucket was chosen when put ran, from the hash of "AB-1". Changing the field changed the hash and did not move the entry, so the key now hashes to a bucket it is not in — and the old key does not exist any more to hash with.
Put this beside the missing hashCode and the shared fact comes out: the map looked in a bucket the entry is not in, and reported the key as absent rather than failing. One got there by hashing differently from the start; this one got there by hashing differently later. The entry is unreachable either way, and size() still counts it.
Use immutable keys, or keys whose equals and hashCode read only fields that never change. A record with final components is the shape that makes this impossible rather than merely unlikely.