The key that changed after it was stored
A hard Java puzzle in the collections contracts family. One line below contains a real bug. Try to spot it first, then read why it fails and how to fix it.
Highlighted: line 15. Play this one as a puzzle without the answer.
What is wrong
The entry was stored in the bucket for hash 1. After changing the key, lookups hash to 2, so get returns null, and the entry can no longer be found or removed, which is a memory leak. Keys must not change while in a map.
The fix
How to avoid it next time
Use immutable objects (strings, records, enums) as map keys and set elements.
Want the background? Read How HashMap works in the Java concepts library.
About collections contracts
Collection classes come with contracts about ordering, mutability and key behavior. Fixed-size lists, views of other collections and mutable map keys break those contracts without compile errors.
In code review: Check what the factory method returns, whether the result is modified later, and whether objects used as keys can change after insertion.
More puzzles in this family
Frequently asked questions
What is the bug in "The key that changed after it was stored"?
The entry was stored in the bucket for hash 1. After changing the key, lookups hash to 2, so get returns null, and the entry can no longer be found or removed, which is a memory leak. Keys must not change while in a map. The faulty line is line 15: k.id = 2;
How do I fix it?
Replace it with: static final class Key { final int id; ... } // immutable key. Use immutable objects (strings, records, enums) as map keys and set elements.
How do I catch collections contracts in code review?
Check what the factory method returns, whether the result is modified later, and whether objects used as keys can change after insertion.
Is there a new puzzle every day?
Yes. The daily Spot the Bug puzzle picks one of these snippets for each UTC day, with the difficulty set by the weekday. Your streak is stored only in your browser.