Ответ
Нет, техническое требование отсутствует, но это критически важная рекомендация.
В однопоточном приложении HashMap не сломается от использования изменяемого ключа, но это приведет к логическим ошибкам и потере данных.
Проблема: HashMap находит значение по хэш-коду ключа и проверке равенства (equals). Если после помещения пары ключ-значение в мапу изменить состояние ключа так, что изменится его hashCode() или результат equals(), то исходное значение станет недостижимым.
Пример:
class MutableKey {
private String value;
// конструктор, геттеры, сеттеры, hashCode, equals
}
Map<MutableKey, String> map = new HashMap<>();
MutableKey key = new MutableKey("initial");
map.put(key, "MyValue");
// Изменяем ключ
key.setValue("changed");
// Попытка найти значение -> вернется null
System.out.println(map.get(key)); // null
// При этом значение "MyValue" осталось в мапе, но "потерялось".
Практические правила:
- Всегда используйте неизменяемые типы для ключей (
String,Integer, собственныеrecordили классы сfinalполями). - Если объект ключа должен быть изменяемым, никогда не модифицируйте его после использования в качестве ключа в HashMap или любом другом хэш-базированном коллекторе.