Класс IdentityHashMap<K, V>
- Параметры типа:
K- тип ключей, хранящихся в этой картеV- тип сопоставленных значений
- Все реализуемые интерфейсы:
Serializable, Cloneable, Map<K,V>
public class IdentityHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Serializable, Cloneable
Map с помощью хеш-таблицы, используя при сравнении ключей (и значений) равенство ссылок вместо равенства объектов. Другими словами, в IdentityHashMap два ключа k1 и k2 считаются равными тогда и только тогда, когда (k1==k2). (В обычных реализациях Map (например, HashMap) два ключа k1 и k2 считаются равными тогда и только тогда, когда (k1==null ? k2==null : k1.equals(k2)).) Этот класс не является реализацией Map общего назначения! Хотя этот класс реализует интерфейс Map, он намеренно нарушает общий контракт Map's, который предписывает использовать метод equals при сравнении объектов. Этот класс предназначен только для редких случаев, когда требуется семантика равенства ссылок.
Для элементов коллекций-представлений этой карты также используется семантика равенства ссылок. Дополнительные сведения см. в методах keySet, values и entrySet.
Типичное применение этого класса — преобразования графов объектов с сохранением топологии, например сериализация или глубокое копирование. Для выполнения такого преобразования программа должна поддерживать «таблицу узлов», отслеживающую все ссылки на объекты, которые уже были обработаны. Таблица узлов не должна считать различные объекты равными, даже если они равны друг другу. Еще один типичный вариант использования этого класса — хранение объектов-прокси. Например, средство отладки может хранить объект-прокси для каждого объекта программы, которая отлаживается.
Этот класс предоставляет все необязательные операции с картами и допускает значения null и ключ null. Этот класс не дает никаких гарантий относительно порядка элементов карты; в частности, не гарантируется, что порядок останется неизменным с течением времени.
Этот класс обеспечивает постоянное время выполнения базовых операций (get и put) при условии, что системная функция хеширования идентичности (System.identityHashCode(Object)) равномерно распределяет элементы по корзинам.
У этого класса есть один параметр настройки (влияющий на производительность, но не на семантику): ожидаемый максимальный размер. Этот параметр задает максимальное число сопоставлений ключ-значение, которое, как ожидается, будет хранить карта. Внутренне этот параметр используется для определения числа корзин, изначально составляющих хеш-таблицу. Точная зависимость между ожидаемым максимальным размером и числом корзин не определена.
Если размер карты (число сопоставлений ключ-значение) значительно превысит ожидаемый максимальный размер, число корзин будет увеличено. Увеличение числа корзин («рехеширование») может быть довольно затратным, поэтому стоит создавать карты идентичности с достаточно большим ожидаемым максимальным размером. С другой стороны, для итерации по коллекциям-представлениям требуется время, пропорциональное числу корзин в хеш-таблице, поэтому не следует задавать слишком большой ожидаемый максимальный размер, если особенно важны производительность итерации или использование памяти.
Обратите внимание, что эта реализация не синхронизирована. Если несколько потоков одновременно обращаются к карте идентичности и хотя бы один из них структурно изменяет карту, доступ должен быть синхронизирован извне. (Структурное изменение — это любая операция, добавляющая или удаляющая одно или несколько сопоставлений; простое изменение значения, связанного с уже имеющимся в экземпляре ключом, не является структурным изменением.) Обычно для этого выполняют синхронизацию по объекту, который естественным образом инкапсулирует карту. Если такого объекта нет, карту следует «обернуть» с помощью метода Collections.synchronizedMap. Лучше всего сделать это при создании карты, чтобы предотвратить случайный несинхронизированный доступ к ней:
Map m = Collections.synchronizedMap(new IdentityHashMap(...));
Итераторы, возвращаемые методом iterator коллекций, полученных всеми методами этого класса, возвращающими «представления коллекций», являются быстро падающими: если после создания итератора карта каким-либо образом структурно изменяется, за исключением вызова собственного метода remove итератора, итератор выбрасывает исключение ConcurrentModificationException. Таким образом, при параллельном изменении итератор быстро и корректно завершает работу, вместо того чтобы рисковать произвольным недетерминированным поведением в неопределенный момент в будущем.
Обратите внимание, что гарантировать поведение итератора с быстрым отказом невозможно, поскольку, вообще говоря, при несинхронизированном параллельном изменении нельзя дать никаких строгих гарантий. Итераторы с быстрым отказом выбрасывают ConcurrentModificationException по возможности. Поэтому было бы неправильно писать программу, корректность которой зависит от этого исключения: итераторы с быстрым отказом следует использовать только для обнаружения ошибок.
Этот класс входит в состав Java Collections Framework.
- Примечание по реализации:
Это простая хеш-таблица с линейным пробированием, описанная, например, в трудах Седжвика и Кнута. Массив содержит чередующиеся ключи и значения: ключи располагаются по четным индексам, а значения — по нечетным. (Для больших таблиц такое расположение обеспечивает лучшую локальность, чем использование отдельных массивов.) Во многих реализациях Java и при многих сочетаниях операций этот класс работает эффективнее, чем
HashMap, в котором используется метод цепочек, а не линейное пробирование.- Начиная с:
- 1.4
- См. также:
Краткое описание вложенных классов
Вложенные классы/интерфейсы, объявленные в классе AbstractMap
AbstractMap.SimpleEntry<K, V>, AbstractMap.SimpleImmutableEntry<K, V>
Краткое описание конструкторов
| Конструктор | Описание |
|---|---|
IdentityHashMap() |
Создает новую пустую карту идентичности с максимальным размером по умолчанию (21). |
IdentityHashMap |
Создает новую пустую карту с указанным ожидаемым максимальным размером. |
IdentityHashMap |
Создает новую карту идентичности, содержащую сопоставления ключ-значение из указанной карты. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
void |
clear() |
Удаляет из этой карты все сопоставления. |
Object |
clone() |
Возвращает поверхностную копию этой карты идентичности: сами ключи и значения не клонируются. |
boolean |
containsKey |
Проверяет, является ли указанная ссылка на объект ключом в этой карте идентичности. |
boolean |
containsValue |
Проверяет, является ли указанная ссылка на объект значением в этой карте идентичности. |
Set |
entrySet() |
Возвращает представление сопоставлений, содержащихся в этой карте, в виде Set. |
boolean |
equals |
Сравнивает указанный объект с этой картой на равенство. |
V |
get |
Возвращает значение, сопоставленное с указанным ключом, или null, если в этой карте нет сопоставления для ключа. |
int |
hashCode() |
Возвращает значение хеш-кода этой карты. |
boolean |
isEmpty() |
Возвращает true, если эта карта идентичности не содержит сопоставлений ключ-значение. |
Set |
keySet() |
Возвращает представление ключей этой карты в виде множества, основанного на идентичности. |
V |
put |
Связывает указанное значение с указанным ключом в этой карте идентичности. |
void |
putAll |
Копирует в эту карту все сопоставления из указанной карты. |
V |
remove |
Удаляет из этой карты сопоставление для данного ключа, если оно существует. |
boolean |
remove |
Удаляет запись для указанного ключа, только если в данный момент ему сопоставлено указанное значение (необязательная операция). |
boolean |
replace |
Заменяет запись для указанного ключа, только если в данный момент ему сопоставлено указанное значение (необязательная операция). |
int |
size() |
Возвращает число сопоставлений ключ-значение в этой карте идентичности. |
Collection |
values() |
Возвращает представление значений, содержащихся в этой карте, в виде Collection. |
Методы, объявленные в классе AbstractMap
toString
Методы, объявленные в интерфейсе Map
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, replace, replaceAll
Подробное описание конструкторов
IdentityHashMap
public IdentityHashMap()
IdentityHashMap
public IdentityHashMap(int expectedMaxSize)
- Параметры:
-
expectedMaxSize— ожидаемый максимальный размер карты - Исключения:
-
IllegalArgumentException— еслиexpectedMaxSizeотрицательно
IdentityHashMap
public IdentityHashMap(Map<? extends K, ? extends V> m)
- Параметры:
-
m— карта, пары из которой нужно поместить в эту карту - Исключения:
-
NullPointerException— если указанная карта равна null
Подробное описание методов
size
isEmpty
public boolean isEmpty()
true, если эта карта идентификаторов с хешированием не содержит пар «ключ-значение».get
public V get(Object key)
null, если в этой карте нет соответствия для ключа. Точнее, если в этой карте есть соответствие ключа k значению v, такое что (key == k), этот метод возвращает v; в противном случае он возвращает null. (Такое соответствие может быть не более чем одно.)
Возвращаемое значение null не обязательно означает, что в карте нет соответствия для ключа; также возможно, что карта явно сопоставляет ключ со значением null. Чтобы различить эти два случая, можно использовать операцию containsKey.
containsKey
public boolean containsKey(Object key)
true тогда и только тогда, когда эта карта содержит соответствие с ключом k, такое что (key == k).- Указан в:
-
containsKeyв интерфейсеMap<K,V> - Переопределяет:
-
containsKeyв классеAbstractMap<K,V> - Параметры:
-
key— возможный ключ - Возвращает:
-
true, если указанная ссылка на объект является ключом в этой карте - См. также:
containsValue
public boolean containsValue(Object value)
true тогда и только тогда, когда эта карта содержит соответствие со значением v, такое что (value == v).- Указан в:
-
containsValueв интерфейсеMap<K,V> - Переопределяет:
-
containsValueв классеAbstractMap<K,V> - Параметры:
-
value— значение, наличие которого в этой карте нужно проверить - Возвращает:
-
true, если эта карта сопоставляет один или несколько ключей с указанной ссылкой на объект - См. также:
put
public V put(K key, V value)
contains есть соответствие для ключа, старое значение заменяется; в противном случае в карту добавляется новое соответствие.- Указан в:
-
putв интерфейсеMap<K,V> - Переопределяет:
-
putв классеAbstractMap<K,V> - Параметры:
-
key— ключ, с которым нужно связать указанное значение -
value— значение, которое нужно связать с указанным ключом - Возвращает:
- предыдущее значение, связанное с
key, илиnull, если дляkeyне было соответствия. (Возвращаемое значениеnullтакже может означать, что ранее карта связывалаnullсо значениемkey.) - См. также:
putAll
public void putAll(Map<? extends K, ? extends V> m)
contains есть соответствие для ключа, его значение заменяется значением из указанной карты; в противном случае в эту карту добавляется новое соответствие.- Указан в:
-
putAllв интерфейсеMap<K,V> - Переопределяет:
-
putAllв классеAbstractMap<K,V> - Параметры:
-
m— соответствия, которые нужно сохранить в этой карте - Исключения:
-
NullPointerException— если указанная карта равна null
remove
public V remove(Object key)
k, такой что (key == k).- Указан в:
-
removeв интерфейсеMap<K,V> - Переопределяет:
-
removeв классеAbstractMap<K,V> - Параметры:
-
key— ключ, соответствие для которого нужно удалить из карты - Возвращает:
- предыдущее значение, связанное с
key, илиnull, если дляkeyне было соответствия. (Возвращаемое значениеnullтакже может означать, что ранее карта связывалаnullсо значениемkey.)
clear
equals
public boolean equals(Object o)
true, если переданный объект также является картой и обе карты представляют одинаковые соответствия ссылок на объекты. Точнее, эта карта равна другой карте m тогда и только тогда, когда this.entrySet().equals(m.entrySet()). Описание равенства записей этой карты см. в методе entrySet. Из-за семантики этой карты, основанной на равенстве ссылок, при сравнении карты с обычной картой требования симметричности и транзитивности контракта Object.equals могут быть нарушены. Однако контракт Object.equals гарантированно выполняется для экземпляров IdentityHashMap.
hashCode
public int hashCode()
entrySet. Это определение гарантирует, что m1.equals(m2) подразумевает m1.hashCode()==m2.hashCode() для любых двух экземпляров IdentityHashMap m1 и m2, как того требует общий контракт Object.hashCode().
Из-за семантики, основанной на равенстве ссылок, у экземпляров Map.Entry в множестве, возвращаемом методом entrySet этой карты, контрактное требование Object.hashCode, упомянутое в предыдущем абзаце, может быть нарушено, если один из двух сравниваемых объектов является экземпляром IdentityHashMap, а другой — обычной картой.
clone
public Object clone()
- Переопределяет:
-
cloneв классеAbstractMap<K,V> - Возвращает:
- поверхностную копию этой карты
- См. также:
keySet
public Set<K> keySet()
Iterator.remove, Set.remove, removeAll, retainAll и clear. Методы add и addAll не поддерживаются. Хотя объект, возвращаемый этим методом, реализует интерфейс Set, он не соблюдает общий контракт Set's. Как и поддерживающая его карта, множество, возвращаемое этим методом, определяет равенство элементов по равенству ссылок, а не объектов. Это влияет на поведение его методов contains, remove, containsAll, equals и hashCode.
Метод equals возвращаемого множества возвращает true только в том случае, если указанный объект — множество, содержащее те же самые ссылки на объекты, что и возвращаемое множество. При сравнении множества, возвращаемого этим методом, с обычным множеством требования симметричности и транзитивности контракта Object.equals могут быть нарушены. Однако контракт Object.equals гарантированно выполняется для множеств, возвращаемых этим методом.
Метод hashCode возвращаемого множества возвращает сумму хеш-кодов идентичности элементов множества, а не сумму их хеш-кодов. Это обусловлено изменением семантики метода equals, необходимым для обеспечения общего контракта метода Object.hashCode для множеств, возвращаемых этим методом.
values
public Collection<V> values()
Collection. Коллекция поддерживается картой, поэтому изменения карты отражаются в коллекции, и наоборот. Если карта изменяется во время перебора коллекции, результаты перебора не определены. Коллекция поддерживает удаление элементов, которое удаляет соответствующее соответствие из карты, с помощью методов Iterator.remove, Collection.remove, removeAll, retainAll и clear. Методы add и addAll не поддерживаются. Хотя объект, возвращаемый этим методом, реализует интерфейс Collection, он не соблюдает общий контракт Collection's. Как и поддерживающая его карта, коллекция, возвращаемая этим методом, определяет равенство элементов по равенству ссылок, а не объектов. Это влияет на поведение ее методов contains, remove и containsAll.
entrySet
public Set<Map.Entry<K,V>> entrySet()
Set. Каждый элемент возвращаемого множества — это Map.Entry, основанный на равенстве ссылок. Множество поддерживается картой, поэтому изменения карты отражаются в множестве, и наоборот. Если карта изменяется во время перебора множества, результаты перебора не определены. Множество поддерживает удаление элементов, которое удаляет соответствующее соответствие из карты, с помощью методов Iterator.remove, Set.remove, removeAll, retainAll и clear. Методы add и addAll не поддерживаются. Как и поддерживающая ее карта, объекты Map.Entry в множестве, возвращаемом этим методом, определяют равенство ключей и значений по равенству ссылок, а не объектов. Это влияет на поведение методов equals и hashCode этих объектов Map.Entry. Map.Entry
e, основанный на равенстве ссылок, равен объекту o тогда и только тогда, когда o является Map.Entry и e.getKey()==o.getKey() &&
e.getValue()==o.getValue(). Чтобы обеспечить такую семантику equals, метод hashCode возвращает System.identityHashCode(e.getKey()) ^
System.identityHashCode(e.getValue()). (Хотя ключи и значения сравниваются по ссылкам, сами объекты Map.Entry — нет.)
Из-за семантики, основанной на равенстве ссылок, у экземпляров Map.Entry в множестве, возвращаемом этим методом, требования симметричности и транзитивности контракта Object.equals(Object) могут быть нарушены, если какая-либо запись множества сравнивается с обычной записью карты или если множество, возвращаемое этим методом, сравнивается с множеством обычных записей карты (например, возвращаемым вызовом этого метода для обычной карты). Однако контракт Object.equals гарантированно выполняется для записей карт, основанных на идентичности объектов, и множеств таких записей.
remove
public boolean remove(Object key, Object value)
Точнее, если в этой карте есть соответствие ключа k значению v, такое что (key == k) и (value == v), этот метод удаляет соответствие для данного ключа и возвращает true; в противном случае он возвращает false.
replace
public boolean replace(K key, V oldValue, V newValue)
Точнее, если в этой карте есть соответствие ключа k значению v, такое что (key == k) и (oldValue == v), этот метод связывает k с newValue и возвращает true; в противном случае он возвращает false.
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/IdentityHashMap.html