- java.lang.Object
-
- java.util.AbstractMap<K,V>
-
- java.util.IdentityHashMap<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==null ? k2==null : k1.equals(k2))
两个密钥k1
和k2
被认为是相等的。)这个类不是通用的
Map
实现! 虽然此类实现了Map
接口,但它故意违反Map's
一般合同,该合同要求在比较对象时使用equals
方法。 此类仅用于需要引用相等语义的罕见情况。此类的典型用法是保留拓扑的对象图转换 ,例如序列化或深度复制。 要执行此类转换,程序必须维护一个“节点表”,以跟踪已处理的所有对象引用。 节点表必须不等同于不同的对象,即使它们碰巧相等。 此类的另一个典型用法是维护代理对象 。 例如,调试工具可能希望为正在调试的程序中的每个对象维护一个代理对象。
此类提供所有可选的映射操作,并允许
null
值和null
键。 这个类不保证地图的顺序; 特别是,它不保证订单会随着时间的推移保持不变。假设系统标识散列函数(
System.identityHashCode(Object)
)在存储桶之间正确地分散元素,则put
为基本操作(get
和put
)提供恒定时间性能。此类有一个调整参数(影响性能但不影响语义): 预期的最大大小 。 此参数是地图预期保留的最大键值映射数。 在内部,此参数用于确定最初包含哈希表的存储桶数。 未指定预期最大大小和桶数之间的精确关系。
如果映射的大小(键值映射的数量)充分超过预期的最大大小,则桶的数量增加。 增加桶的数量(“rehashing”)可能相当昂贵,因此创建具有足够大的预期最大大小的身份哈希映射是值得的。 另一方面,对集合视图的迭代需要与哈希表中的桶数成比例的时间,因此如果您特别关注迭代性能或内存使用,则不应将预期的最大大小设置得太高。
请注意,此实现不同步。 如果多个线程同时访问标识哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)这通常通过同步自然封装映射的某个对象来完成。 。 如果不存在此类对象,则应使用
Collections.synchronizedMap
方法“包装”地图。 这最好在创建时完成,以防止意外地不同步访问地图:Map m = Collections.synchronizedMap(new IdentityHashMap(...));
由所有类的“集合视图方法”返回的集合的
iterator
方法返回的迭代器是快速失败的 :如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove
方法,迭代器将抛出ConcurrentModificationException
。 因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险。请注意,迭代器的快速失败行为无法得到保证,因为一般来说,在存在不同步的并发修改时,不可能做出任何硬性保证。 失败快速迭代器以尽力而为的方式抛出
ConcurrentModificationException
。 因此,编写依赖于此异常的程序以确保其正确性是错误的: 故障快速迭代器应仅用于检测错误。实现说明:这是一个简单的线性探测哈希表,如Sedgewick和Knuth的文本中所述。 数组交替显示保持键和值。 (对于大型表,这比使用单独的数组具有更好的局部性。)对于许多JRE实现和操作混合,此类将产生比
HashMap
(使用链接而不是线性探测)更好的性能。本课程是Java Collections Framework的成员。
- 从以下版本开始:
- 1.4
- 另请参见:
-
System.identityHashCode(Object)
,Object.hashCode()
,Collection
,Map
,HashMap
,TreeMap
, Serialized Form
-
-
嵌套类汇总
-
嵌套类/接口声明在类 java.util.AbstractMap
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>
-
-
构造方法摘要
构造方法 构造器 描述 IdentityHashMap()
使用默认的预期最大大小构造一个新的空标识哈希映射(21)。IdentityHashMap(int expectedMaxSize)
使用指定的预期最大大小构造一个新的空映射。IdentityHashMap(Map<? extends K,? extends V> m)
构造一个新的标识哈希映射,其中包含指定映射中的键 - 值映射。
-
方法摘要
所有方法 实例方法 具体的方法 变量和类型 方法 描述 void
clear()
从此映射中删除所有映射。Object
clone()
返回此标识哈希映射的浅表副本:不克隆键和值本身。boolean
containsKey(Object key)
测试指定的对象引用是否是此标识哈希映射中的键。boolean
containsValue(Object value)
测试指定的对象引用是否是此标识哈希映射中的值。Set<Map.Entry<K,V>>
entrySet()
返回此映射中包含的映射的Set
视图。boolean
equals(Object o)
将指定对象与此映射进行比较以获得相等性。V
get(Object key)
返回指定键映射到的值,如果此映射不包含键的映射,则返回null
。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)
从此映射中删除此键的映射(如果存在)。int
size()
返回此标识哈希映射中键 - 值映射的数量。Collection<V>
values()
返回此映射中包含的值的Collection
视图。-
声明方法的类 java.util.AbstractMap
toString
-
声明方法的接口 java.util.Map
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, remove, replace, replace, replaceAll
-
-
-
-
构造方法详细信息
-
IdentityHashMap
public IdentityHashMap()
使用默认的预期最大大小构造一个新的空标识哈希映射(21)。
-
IdentityHashMap
public IdentityHashMap(int expectedMaxSize)
使用指定的预期最大大小构造一个新的空映射。 将超过预期数量的键值映射放入映射可能会导致内部数据结构增长,这可能有些耗时。- 参数
-
expectedMaxSize
- 地图的预期最大大小 - 异常
-
IllegalArgumentException
- 如果expectedMaxSize
为负数
-
IdentityHashMap
public IdentityHashMap(Map<? extends K,? extends V> m)
构造一个新的标识哈希映射,其中包含指定映射中的键 - 值映射。- 参数
-
m
-m
映射放入此映射的映射 - 异常
-
NullPointerException
- 如果指定的映射为null
-
-
方法详细信息
-
size
public int size()
返回此标识哈希映射中键 - 值映射的数量。
-
isEmpty
public boolean isEmpty()
如果此标识哈希映射不包含键 - 值映射,则返回true
。
-
get
public V get(Object key)
返回指定键映射到的值,如果此映射不包含键的映射,则返回null
。更正式地说,如果此映射包含从键
k
到值v
的映射,使得(key == k)
,则此方法返回v
; 否则返回null
。 (最多可以有一个这样的映射。)返回值
null
不一定表示映射不包含键的映射; 地图也可能明确地将密钥映射到null
。 可以使用containsKey
操作来区分这两种情况。- Specified by:
-
get
在界面Map<K,V>
- 重写:
-
get
在类AbstractMap<K,V>
- 参数
-
key
- 要返回其关联值的键 - 结果
-
指定键映射到的值,如果此映射不包含键的映射,
null
- 另请参见:
-
put(Object, Object)
-
containsKey
public boolean containsKey(Object key)
测试指定的对象引用是否是此标识哈希映射中的键。- Specified by:
-
containsKey
在界面Map<K,V>
- 重写:
-
containsKey
在课程AbstractMap<K,V>
- 参数
-
key
- 可能的关键 - 结果
-
true
如果指定的对象引用是此映射中的键 - 另请参见:
-
containsValue(Object)
-
containsValue
public boolean containsValue(Object value)
测试指定的对象引用是否是此标识哈希映射中的值。- Specified by:
-
containsValue
在界面Map<K,V>
- 重写:
-
containsValue
在类AbstractMap<K,V>
- 参数
-
value
- 要测试其在此地图中的存在的值 - 结果
-
true
如果此映射将一个或多个键映射到指定的对象引用 - 另请参见:
-
containsKey(Object)
-
put
public V put(K key, V value)
将指定的值与此标识哈希映射中的指定键相关联。 如果映射先前包含键的映射,则替换旧值。- Specified by:
-
put
在界面Map<K,V>
- 重写:
-
put
类AbstractMap<K,V>
- 参数
-
key
- 与指定值关联的键 -
value
- 与指定键关联的值 - 结果
-
先前的值相关联的
key
,或null
如果没有映射key
。 (Anull
返回也可以表示该映射以前关联null
与key
)。 - 另请参见:
-
Object.equals(Object)
,get(Object)
,containsKey(Object)
-
putAll
public void putAll(Map<? extends K,? extends V> m)
将指定映射中的所有映射复制到此映射。 这些映射将替换此映射对当前位于指定映射中的任何键的任何映射。- Specified by:
-
putAll
在界面Map<K,V>
- 重写:
-
putAll
在类AbstractMap<K,V>
- 参数
-
m
- 要存储在此映射中的映射 - 异常
-
NullPointerException
- 如果指定的映射为null
-
clear
public void clear()
从此映射中删除所有映射。 此调用返回后,映射将为空。
-
equals
public boolean equals(Object o)
将指定对象与此映射进行比较以获得相等性。 如果给定对象也是映射,则返回true
,并且两个映射表示相同的对象引用映射。 更正式的是,这张地图等于另一张地图m
当且仅当this.entrySet().equals(m.entrySet())
。由于此映射的基于引用相等的语义,如果将此映射与法线映射进行比较,则可能违反
Object.equals
合同的对称性和传递性要求。 但是,Object.equals
合约保证在IdentityHashMap
实例中持有。- Specified by:
-
equals
in interfaceMap<K,V>
- 重写:
-
equals
在类AbstractMap<K,V>
- 参数
-
o
- 要与此映射进行相等性比较的对象 - 结果
-
true
如果指定的对象等于此映射 - 另请参见:
-
Object.equals(Object)
-
hashCode
public int hashCode()
返回此映射的哈希码值。 地图的哈希码被定义为地图entrySet()
视图中每个条目的哈希码的总和。 这确保m1.equals(m2)
暗示m1.hashCode()==m2.hashCode()
对于任何两个IdentityHashMap
实例m1
和m2
,根据m2
的一般合同的要求 。由于此映射的
entrySet
方法返回的集合中的Map.Entry
实例的基于引用相等的语义,如果被比较的两个对象之一是一个,则可能违反前一段中提到的合同要求Object.hashCode
IdentityHashMap
实例和另一个是法线贴图。- Specified by:
-
hashCode
in interfaceMap<K,V>
- 重写:
-
hashCode
在类AbstractMap<K,V>
- 结果
- 此映射的哈希码值
- 另请参见:
-
Object.equals(Object)
,equals(Object)
-
clone
public Object clone()
返回此标识哈希映射的浅表副本:不克隆键和值本身。- 重写:
-
clone
在类AbstractMap<K,V>
- 结果
- 这张地图的浅表副本
- 另请参见:
-
Cloneable
-
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
方法的常规协定。- Specified by:
-
keySet
在界面Map<K,V>
- 重写:
-
keySet
类AbstractMap<K,V>
- 结果
- 此映射中包含的键的基于标识的集合视图
- 另请参见:
-
Object.equals(Object)
,System.identityHashCode(Object)
-
values
public Collection<V> values()
返回此映射中包含的值的Collection
视图。 该集合由地图支持,因此对地图的更改将反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射,则迭代的结果是未定义的。 该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
对象将键和值相等定义为引用相等而不是对象相等。 这会影响这些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
实例的基于引用相等的语义,如果将集合中的任何条目与正常条目进行比较,则可能违反Object.equals(Object)
合同的对称性和传递性要求映射条目,或者将此方法返回的集合与一组正常映射条目(例如通过在法线映射上调用此方法返回)进行比较。 但是,Object.equals
合同保证在基于身份的映射条目和这些条目集之间保持。
-
-