Что запрещено модифицировать в HashMap и почему?

«Что запрещено модифицировать в HashMap и почему?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В HashMap запрещено изменять (мутировать) объект, используемый в качестве ключа, после того как он был добавлен в мапу. Это правило критично для корректной работы структуры.

Причина: HashMap хранит пары ключ-значение в «корзинах» (buckets), индекс которых вычисляется на основе хеш-кода ключа (hashCode()). Если ключ изменяется после вставки, его хеш-код может стать другим. В результате:

  • Метод get() не найдет запись, так будет искать её в корзине по новому хешу.
  • Возникает «потерянное» значение, которое невозможно получить или удалить стандартными методами.

Пример проблемы с изменяемым ключом:

class MutableKey {
    int id;
    MutableKey(int id) { this.id = id; }
    public void setId(int id) { this.id = id; }
    @Override public int hashCode() { return id; }
    // equals также должен зависеть от id
}

HashMap<MutableKey, String> map = new HashMap<>();
MutableKey key = new MutableKey(1);
map.put(key, "Data");

key.setId(100); // КАТАСТРОФА: Изменение ключа!
System.out.println(map.get(key)); // Вывод: null — запись потеряна.

Best Practice: Используйте в качестве ключей иммутабельные (неизменяемые) классы, такие как String, Integer, LocalDate или создавайте собственные классы с final полями.