Card 07/ 08
All 8 cards
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.
// 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?
| Class | Safe? | Why |
|---|---|---|
A | Yes, but only as identity | Neither method overridden, so a key works only if you keep the very same object |
B | No | equals without hashCode — two equal keys land in different buckets |
C | Yes | A record supplies both from its components, and they are final |
D | No | Both 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.