В чём особенность IdentityHashMap в Java и когда его используют?

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

Ответ

IdentityHashMap — это специализированная реализация интерфейса Map, которая для сравнения ключей использует оператор равенства ссылок (==), а не методы equals() и hashCode(). Это нарушает общий контракт Map, но полезно в специфических сценариях.

Основное отличие от HashMap:

Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> identityMap = new IdentityHashMap<>();

String key1 = new String("key");
String key2 = new String("key"); // Другой объект в памяти, но equals() возвращает true

hashMap.put(key1, 1);
hashMap.put(key2, 1); // Ключи считаются равными по equals(), значение перезапишется
System.out.println(hashMap.size()); // 1

identityMap.put(key1, 1);
identityMap.put(key2, 2); // Ключи РАЗНЫЕ по ссылке (key1 != key2), добавится новая запись
System.out.println(identityMap.size()); // 2

Типичные случаи использования:

  1. Работа с объектами, где важна идентичность (identity), а не состояние. Например, десериализация одного и того же объекта несколько раз может создать разные экземпляры с одинаковым содержимым.
  2. Обход стандартного поведения equals(). Некоторые системные классы (например, Class) могут кэшироваться или иметь неочевидную реализацию equals().
  3. Реализация топологических алгоритмов, где нужно отслеживать посещённые узлы графа по ссылке, а не по содержимому.

Важное предупреждение: Поскольку IdentityHashMap не использует hashCode(), он менее эффективен для ключей-String литералов из пула строк (где == может совпадать). Используйте его осознанно, только когда требуется сравнение по ссылке.