awelgorithms

Map keys must be immutable

Updated

The bucket of a pair is hash(key) at put time. If you change the key object afterward, its hash and equals change, and the pair sits in the old bucket under the old identity. Later get with either the old or new shape misses.

What to focus on

Integers and strings are safe. A list or a nested map used as a key is not, unless you freeze it or copy it before put. Replacing the value under a key is fine: that does not move the key.

Worked examples

mutate after put

a = [1, 2] used as key → 9, then a[0]=8
  1. put hashed [1,2]
  2. object is now [8,2]

Result: get([1,2]) and get([8,2]) both miss

immutable int

a = [4] as {4:2}, you cannot mutate 4
  1. key is still 4

Result: get(4)=2

replace value only

a = [4] as {4:2}, put 4→0
  1. same key
  2. new value

Result: {4:0} — still findable

Try it

Write showKeyBug(). No arguments. Print the three cases below. Put mutable [1, 2] as a key to 9, then set a[0]=8: get([1,2]) and get([8,2]) both miss. a = [1, 2] used as key → 9, then a[0]=8 → get([1,2]) and get([8,2]) both miss. a = [4] as {4:2}, you cannot mutate 4 → get(4)=2. a = [4] as {4:2}, put 4→0 → {4:0} — still findable.

Integer keys are safe. Mutable list keys are shown only to demonstrate the bug.