public class IdentityHashMap
extends AbstractMap<K, V>
implements Map<K, V>, Serializable, Cloneable
java.lang.Object | ||
↳ | java.util.AbstractMap<K, V> | |
↳ | java.util.IdentityHashMap<K, V> |
此类使用散列表实现Map接口,比较键(和值)时使用引用相等性代替对象相等性。 换句话说,在IdentityHashMap中 ,当且仅当(k1==k2)时 ,两个键k1和k2被认为是相等的。 (在正常的Map实现中(如HashMap ),当且仅当(k1==null ? k2==null : k1.equals(k2))时,两个键k1和k2被视为相等。)
这个类不是通用的Map实现! 虽然此类实现了Map接口,但它故意违反了Map's一般合同,该合同在比较对象时要求使用equals方法。 此类仅用于需要引用相等语义的罕见情况。
这个类的典型用途是拓扑保留对象图转换 ,如序列化或深度复制。 为了执行这种转换,程序必须维护一个“节点表”,用于跟踪所有已处理的对象引用。 节点表不能等同不同的对象,即使它们恰好相等。 此类的另一个典型用途是维护代理对象 。 例如,调试工具可能希望为正在调试的程序中的每个对象维护一个代理对象。
该类提供所有可选的映射操作,并允许null值和null键。 这个类不能保证地图的顺序; 特别是,它不能保证订单会随着时间的推移保持不变。
假设系统身份散列函数( identityHashCode(Object)
)将元素正确分散到存储桶中, 此类为基本操作( get和 put )提供恒定时间性能。
该类有一个调整参数(影响性能但不影响语义): 预期的最大大小 。 此参数是映射预期保存的键 - 值映射的最大数量。 在内部,该参数用于确定最初包含散列表的桶的数量。 预期的最大大小和桶的数量之间的确切关系是未指定的。
如果映射的大小(键值映射的数量)充分超过了预期的最大大小,则桶的数量会增加增加桶的数量(“重新哈希”)可能相当昂贵,因此创建身份哈希值是值得的具有足够大的预期最大尺寸的地图。 另一方面,对集合视图的迭代需要的时间与哈希表中桶的数量成正比,所以如果您特别关心迭代性能或内存使用情况,则不要将期望的最大大小设置得太高。
请注意,此实现不同步。 如果多个线程同时访问标识哈希映射,并且至少有一个线程在结构上修改了映射,则它必须在外部同步。 (结构修改是指添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键相关联的值不是结构修改。)这通常通过同步某个自然封装映射的对象来实现。 如果不存在这样的对象,则应该使用Collections.synchronizedMap
方法“映射”地图。 这最好在创建时完成,以防止意外的不同步访问地图:
Map m = Collections.synchronizedMap(new IdentityHashMap(...));
由所有这个类的“集合视图方法”返回的集合的iterator方法返回的迭代器快速失败 :如果在创建迭代器后的任何时候结构性地修改映射,除了通过迭代器自己的remove方法,迭代器将抛出一个ConcurrentModificationException
。 因此,面对并发修改,迭代器快速而干净地失败,而不是在将来某个未确定的时间冒着任意的,非确定性的行为风险。
请注意,迭代器的故障快速行为无法得到保证,因为一般来说,在存在非同步并发修改的情况下不可能做出任何硬性保证。 失败快速迭代器尽最大努力抛出ConcurrentModificationException 。 因此,编写一个依赖于此异常的程序是正确的:编写失败快速迭代器只能用于检测错误。
实现注释:这是一个简单的线性探测哈希表,正如Sedgewick和Knuth的文本中所述。 数组交替保存键和值。 (与使用单独数组相比,这对于大型表具有更好的局部性。)对于许多JRE实现和操作混合,此类将产生比HashMap
(使用链接而不是线性探测)更好的性能。
此课程是 Java Collections Framework的成员。
Public constructors |
|
---|---|
IdentityHashMap() 使用默认的预期最大大小构造一个新的空白身份哈希映射(21)。 |
|
IdentityHashMap(int expectedMaxSize) 用指定的预期最大尺寸构造一个新的空白地图。 |
|
IdentityHashMap(Map<? extends K, ? extends V> m) 构造一个新的标识哈希映射,其中包含指定映射中的键值映射。 |
Public methods |
|
---|---|
void |
clear() 从此映射中移除所有映射。 |
Object |
clone() 返回此身份哈希映射的浅表副本:键和值本身未被克隆。 |
boolean |
containsKey(Object key) 测试指定的对象引用是否是此身份散列映射中的键。 |
boolean |
containsValue(Object value) 测试指定的对象引用是否是此身份散列映射中的值。 |
Set<Entry<K, V>> |
entrySet() 返回此映射中包含的映射的 |
boolean |
equals(Object o) 将指定的对象与此映射进行比较以获得相等性。 |
void |
forEach(BiConsumer<? super K, ? super V> action) 对此映射中的每个条目执行给定操作,直到处理完所有条目或操作抛出异常为止。 |
V |
get(Object key) 返回指定键映射到的值,或者如果此映射不包含键映射,则返回 |
int |
hashCode() 返回此映射的哈希码值。 |
boolean |
isEmpty() 如果此标识哈希映射不包含键 - 值映射,则返回 true 。 |
Set<K> |
keySet() 返回此映射中包含的键的基于标识的集合视图。 |
V |
put(K key, V value) 将指定的值与此身份散列映射中的指定键相关联。 |
void |
putAll(Map<? extends K, ? extends V> m) 将指定地图中的所有映射复制到此地图。 |
V |
remove(Object key) 如果存在,则从该映射中移除该键的映射。 |
void |
replaceAll(BiFunction<? super K, ? super V, ? extends V> function) 用对该条目调用给定函数的结果替换每个条目的值,直到处理完所有条目或者该函数抛出异常。 |
int |
size() 返回此标识哈希映射中键 - 值映射的数量。 |
Collection<V> |
values() 返回此映射中包含的值的 |
Inherited methods |
|
---|---|
From class java.util.AbstractMap
|
|
From class java.lang.Object
|
|
From interface java.util.Map
|
IdentityHashMap (int expectedMaxSize)
用指定的预期最大尺寸构造一个新的空白地图。 将超过预期数量的键值映射到映射中可能会导致内部数据结构增长,这可能会耗费一些时间。
Parameters | |
---|---|
expectedMaxSize |
int : the expected maximum size of the map |
Throws | |
---|---|
IllegalArgumentException |
if expectedMaxSize is negative |
IdentityHashMap (Map<? extends K, ? extends V> m)
构造一个新的标识哈希映射,其中包含指定映射中的键值映射。
Parameters | |
---|---|
m |
Map : the map whose mappings are to be placed into this map |
Throws | |
---|---|
NullPointerException |
if the specified map is null |
Object clone ()
返回此身份哈希映射的浅表副本:键和值本身未被克隆。
Returns | |
---|---|
Object |
a shallow copy of this map |
boolean containsKey (Object key)
测试指定的对象引用是否是此身份散列映射中的键。
Parameters | |
---|---|
key |
Object : possible key |
Returns | |
---|---|
boolean |
true if the specified object reference is a key in this map |
也可以看看:
boolean containsValue (Object value)
测试指定的对象引用是否是此身份散列映射中的值。
Parameters | |
---|---|
value |
Object : value whose presence in this map is to be tested |
Returns | |
---|---|
boolean |
true if this map maps one or more keys to the specified object reference |
也可以看看:
Set<Entry<K, V>> entrySet ()
返回此映射中包含的映射的Set
视图。 返回集合中的每个元素都是一个基于引用等同的Map.Entry 。 该集合由地图支持,因此对地图的更改反映在集合中,反之亦然。 如果在迭代过程中修改了映射,则迭代的结果是未定义的。 该组支持元件移除,即从映射中相应的映射,经由Iterator.remove,Set.remove,removeAll,retainAll clear和方法。 它不支持add或addAll方法。
与支持映射一样,此方法返回的集合中的Map.Entry对象将键和值相等定义为引用相等,而不是对象相等。 这会影响这些Map.Entry对象的equals和hashCode方法的行为。 基于Map.Entry e甲引用相等等于一个对象o当且仅当o是Map.Entry e.getKey()==o.getKey() && e.getValue()==o.getValue()和。 为了适应这些等价语义, hashCode方法返回System.identityHashCode(e.getKey()) ^ System.identityHashCode(e.getValue()) 。
由于此方法返回的集合中的Map.Entry实例的基于引用等同的语义,如果集合中的任何条目与正常情况进行比较,则可能违反equals(Object)
合约的对称性和传递性要求地图条目,或者将此方法返回的集合与一组普通地图条目进行比较(例如,通过在法线地图上对此方法的调用返回)。 但是, Object.equals合同保证在基于身份的映射条目以及这些条目的集合之间。
Returns | |
---|---|
Set<Entry<K, V>> |
a set view of the identity-mappings contained in this map |
boolean equals (Object o)
将指定的对象与此映射进行比较以获得相等性。 如果给定的对象也是一个映射,并且这两个映射表示相同的对象引用映射,则返回true 。 更正式的说,这张地图等于另一张地图m当且仅当this.entrySet().equals(m.entrySet()) 。
由于该映射的基于引用等同的语义,如果该映射与法线映射进行比较,则可能违反Object.equals合约的对称性和传递性要求。 但是, Object.equals合同保证在IdentityHashMap实例之间。
Parameters | |
---|---|
o |
Object : object to be compared for equality with this map |
Returns | |
---|---|
boolean |
true if the specified object is equal to this map |
也可以看看:
void forEach (BiConsumer<? super K, ? super V> action)
对此映射中的每个条目执行给定操作,直到处理完所有条目或操作抛出异常为止。 除非实现类另有规定,否则按照条目集迭代的顺序执行操作(如果指定了迭代顺序)。操作抛出的异常会中继给调用者。
Parameters | |
---|---|
action |
BiConsumer : The action to be performed for each entry |
V get (Object key)
返回指定键映射到的值,或者如果此映射不包含键映射,则返回 null
。
更正式地说,如果该映射包含从键k
到值v
的映射,例如(key == k)
,则该方法返回v
; 否则返回null
。 (最多可以有一个这样的映射。)
返回值null
并不一定表示该映射不包含该键的映射; 地图也可能明确将密钥映射到null
。 containsKey
操作可能用于区分这两种情况。
Parameters | |
---|---|
key |
Object : the key whose associated value is to be returned |
Returns | |
---|---|
V |
the value to which the specified key is mapped, or null if this map contains no mapping for the key |
也可以看看:
int hashCode ()
返回此映射的哈希码值。 地图的哈希码定义为地图entrySet()视图中每个条目的哈希码的总和。 这确保了m1.equals(m2)意味着m1.hashCode()==m2.hashCode()对于任何两个IdentityHashMap实例m1和m2,所要求的一般合同hashCode()
。
由于该映射的entrySet方法返回的集合中的Map.Entry实例的基于引用等同的语义,有可能违反上一段中提到的Object.hashCode的合同要求,如果比较的两个对象之一是IdentityHashMap实例,另一个是法线图。
Returns | |
---|---|
int |
the hash code value for this map |
也可以看看:
boolean isEmpty ()
如果此标识哈希映射不包含键 - 值映射,则返回 true 。
Returns | |
---|---|
boolean |
true if this identity hash map contains no key-value mappings |
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方法的一般合同。
Returns | |
---|---|
Set<K> |
an identity-based set view of the keys contained in this map |
V put (K key, V value)
将指定的值与此身份散列映射中的指定键相关联。 如果地图先前包含密钥的映射,则旧值将被替换。
Parameters | |
---|---|
key |
K : the key with which the specified value is to be associated |
value |
V : the value to be associated with the specified key |
Returns | |
---|---|
V |
the previous value associated with key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with key.) |
void putAll (Map<? extends K, ? extends V> m)
将指定地图中的所有映射复制到此地图。 这些映射将替换此映射对当前指定映射中的任何键的任何映射。
Parameters | |
---|---|
m |
Map : mappings to be stored in this map |
Throws | |
---|---|
NullPointerException |
if the specified map is null |
V remove (Object key)
如果存在,则从该映射中移除该键的映射。
Parameters | |
---|---|
key |
Object : key whose mapping is to be removed from the map |
Returns | |
---|---|
V |
the previous value associated with key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with key.) |
void replaceAll (BiFunction<? super K, ? super V, ? extends V> function)
用对该条目调用给定函数的结果替换每个条目的值,直到处理完所有条目或者该函数抛出异常。 函数抛出的异常会传递给调用者。
Parameters | |
---|---|
function |
BiFunction : the function to apply to each entry |
int size ()
返回此标识哈希映射中键 - 值映射的数量。
Returns | |
---|---|
int |
the number of key-value mappings in this map |
Collection<V> values ()
返回此映射中包含的值的Collection
视图。 该集合由地图支持,因此地图的更改会反映在集合中,反之亦然。 如果在迭代集合的过程中修改了映射,则迭代的结果是未定义的。 该collection支持元素移除,即从映射中相应的映射,经由Iterator.remove,Collection.remove,removeAll,retainAll clear和方法。 它不支持add或addAll方法。
虽然此方法返回的对象实现了Collection接口,但它不服从Collection's一般合同。 与其支持映射一样,此方法返回的集合将元素相等定义为引用相等,而不是对象相等。 这会影响其contains,remove和containsAll方法的行为。
Returns | |
---|---|
Collection<V> |
a collection view of the values contained in this map |