Подтвердить что ты не робот

Использовать случаи для IdentityHashMap

Может кто-нибудь рассказать, какие важные случаи использования IdentityHashMap?

4b9b3361

Ответ 1

В документах говорится:

Типичное использование этого класса графа объектов, сохраняющих топологию преобразования, такие как сериализация или глубокое копирование. Для выполнения такой преобразования, программа должна сохранить таблицу node, которая хранит отслеживать все ссылки на объекты которые уже обработаны. Таблица node не должна объектов, даже если они равны. Другое типичное использование этого класс - поддерживать прокси-объекты. Например, средство отладки возможно, захочет сохранить прокси-объект для каждого объекта в программе, являющегося отлажено.

Ответ 2

Всякий раз, когда вы хотите, чтобы ваши ключи не сравнивались с equals, но с помощью == вы использовали IdentityHashMap. Это может быть очень полезно, если вы выполняете большую обработку ссылок, но ограничиваетесь только особыми случаями.

Ответ 3

В одном случае, когда вы можете использовать IdentityHashMap, ваши ключи являются объектами класса. Это примерно на 33% быстрее, чем у HashMap! Вероятно, он использует меньше памяти.

Ответ 4

HashMap создает объекты Entry каждый раз, когда вы добавляете объект, который может наложить большой упор на GC, когда у вас много объектов. В HashMap с 1000 объектами или более, вы в конечном итоге используете хорошую часть своего процессора, просто имея записи очистки GC (в ситуациях, таких как поиск путей или другие коллективные снимки, созданные и очищенные). У IdentityHashMap нет этой проблемы, поэтому она будет значительно быстрее.

Смотрите здесь: http://www.javagaming.org/index.php/topic,21395.0/topicseen.html

Ответ 5

Это практический опыт от меня:

IdentityHashMap оставляет гораздо меньшую площадь памяти по сравнению с HashMap для больших мощностей.

Ответ 6

Вы также можете использовать IdentityHashMap как карту общего назначения , если, вы можете убедиться, что объекты, используемые вами как ключи, будут равны, если и только если их ссылки равны.

Какую выгоду? Очевидно, что это будет быстрее и будет использовать меньше памяти, чем использование таких реализаций, как HashMap или TreeMap.


На самом деле, есть много дел, когда это стоит. Например:

  • Enum s. Хотя для перечислений есть еще лучшая альтернатива: EnumMap
  • Class объектов. Они также сопоставимы по ссылке.
  • Interned String s. Либо указывая их как литералы, либо называя String.intern() на них.
  • Кэшированные экземпляры. Некоторые классы обеспечивают кэширование своих экземпляров. Например, цитируя из javadoc Integer.valueOf(int):

    Этот метод всегда будет кэшировать значения в диапазоне от -128 до 127, включительно...

  • Некоторые библиотеки/фреймворки будут управлять точно одним экземпляром типов ceratin, например Spring beans.
  • Типы Singleton. Если вы используете istances типов, которые построены с помощью шаблона Singleton, вы также можете быть уверены, что из них один экземпляр существует, и поэтому тестовый тест равенства будет квалифицирован для теста равенства.
  • Любой другой тип, в котором вы явно используете только те же ссылки для доступа к значениям, которые использовались для размещения значений на карте.

Чтобы продемонстрировать последнюю точку:

Map<Object, String> m = new IdentityHashMap<>();

// Any keys, we keep their references
Object[] keys = { "strkey", new Object(), new Integer(1234567) };

for (int i = 0; i < keys.length; i++)
    m.put(keys[i], "Key #" + i);

// We query values from map by the same references:
for (Object key : keys)
    System.out.println(key + ": " + m.get(key));

Выход будет, как и ожидалось (потому что мы использовали те же Object ссылки на значения запроса с карты):

strkey: Key #0
[email protected]: Key #1
1234567: Key #2

Ответ 7

Важным случаем является то, что вы имеете дело со ссылочными типами (в отличие от значений), и вы действительно хотите получить правильный результат. В злонамеренных объектах могут быть переопределены методы hashCode и equals, которые подходят ко всем видам вреда. К сожалению, он не используется так часто, как должно быть. Если типы интерфейсов, с которыми вы работаете, не переопределяйте hashCode и equals, вы обычно должны идти за IdentityHashMap.