Card 07/ 08

ExerciseDifficulty: Advanced1 min

Four Classes: Which Are Safe as Map Keys

Four classes. Decide for each whether it can be used as a HashMap key without losing entries, and write all four down before opening the reveal.

java
// 1
class A { final String id; }

// 2
class B { final String id;
    @Override public boolean equals(Object o) { /* compares id */ }
}

// 3
record C(String id, long pence) { }

// 4
class D { String id;
    @Override public boolean equals(Object o) { /* compares id */ }
    @Override public int hashCode() { return Objects.hash(id); }
}
Which of the four are safe, and what goes wrong in the others?
Each class, whether it is safe as a key, and why
ClassSafe?Why
AYes, but only as identityNeither method overridden, so a key works only if you keep the very same object
BNoequals without hashCode — two equal keys land in different buckets
CYesA record supplies both from its components, and they are final
DNoBoth overridden correctly, and id is not final — changing it strands the entry

A is the interesting answer. It is not broken: it behaves exactly as intended, and what it means by a key is "this particular object". That is right for something like a cache keyed on an instance, and wrong for anything you will look up by value.

D is the one people miss, because it looks like the correct version. Correct methods reading a mutable field is the same bug arriving later.