Варианты использования для IdentityHashMap - PullRequest
52 голосов
/ 08 мая 2009

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

Ответы [ 7 ]

33 голосов
/ 08 мая 2009

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

30 голосов
/ 08 мая 2009

документация говорит:

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

21 голосов
/ 21 октября 2009

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

17 голосов
/ 17 октября 2014

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

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


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

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

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

  • Некоторые библиотеки / фреймворки будут управлять только одним экземпляром типов Ceratin, например Spring bean.
  • Синглтон-типы. Если вы используете экземпляры типов, построенных по шаблону 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
java.lang.Object@1c29bfd: Key #1
1234567: Key #2
16 голосов
/ 21 октября 2009

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

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

12 голосов
/ 15 октября 2009

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

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

3 голосов
/ 29 декабря 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...