模块 java.base
 java.util

类 IdentityHashMap<K,V>

java.lang.Object
java.util.AbstractMap <K,V>
java.util.IdentityHashMap<K,V>
类型参数:
K - 此map维护的键类型
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) 时,两个键 k1k2 被认为是相等的。 (在正常的 Map 实现中(如 HashMap )当且仅当 (k1==null ? k2==null : k1.equals(k2)) 时,两个键 k1k2 被认为是相等的。)

这堂课是not一个通用的Map实现!虽然此类实现了 Map 接口,但它故意违反了 Map's 通用契约,该契约要求在比较对象时使用 equals 方法。此类旨在仅在需要引用相等语义的极少数情况下使用。

该map的视图集合的元素也具有引用相等语义。有关详细信息,请参阅 keySet values entrySet 方法。

这个类的一个典型用途是拓扑保持对象图变换,例如序列化或深度复制。要执行这样的转换,程序必须维护一个“节点表”,用于跟踪所有已处理的对象引用。节点表不能使不同的对象相等,即使它们恰好相等。此类的另一个典型用途是维护代理对象.例如,调试工具可能希望为被调试程序中的每个对象维护一个代理对象。

此类提供所有可选的map操作,并允许 null 值和 null 键。此类不保证map的顺序;特别是,它不保证顺序会随着时间的推移保持不变。

此类为基本操作(getput)提供恒定时间性能,假设系统身份哈希函数(System.identityHashCode(Object) )将元素适当地分散在桶中。

此类有一个调整参数(影响性能但不影响语义):预期的最大尺寸.此参数是映射预期包含的键值映射的最大数量。在内部,此参数用于确定最初组成哈希表的桶数。未指定预期最大大小和桶数之间的精确关系。

如果map的大小(键值映射的数量)充分超过预期的最大大小,则增加桶的数量。增加桶的数量(“重新哈希”)可能相当昂贵,因此创建具有足够大的预期最大大小的标识hash map是值得的。另一方面,对集合视图的迭代需要的时间与哈希表中的桶数成正比,因此如果您特别关注迭代性能或内存使用,最好不要将预期的最大大小设置得太高。

请注意,此实现不是同步的。 如果多个线程同时访问一个身份hash map,并且至少有一个线程在结构上修改了该map,则它必须外部同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)这通常是通过同步某些自然封装映射的对象来实现的.如果不存在这样的对象,则应使用 Collections.synchronizedMap 方法“包装”map。这最好在创建时完成,以防止意外的不同步访问map:

  Map m = Collections.synchronizedMap(new IdentityHashMap(...));

该类所有“集合视图方法”返回的集合的iterator方法返回的迭代器是快速失败:如果在创建迭代器后的任何时间以任何方式修改map的结构,除了通过迭代器自己的 remove 方法,迭代器将抛出一个 ConcurrentModificationException 。因此,面对并发修改,迭代器会快速干净地失败,而不是冒着在未来不确定的时间出现任意的、不确定的行为的风险。

请注意,无法保证迭代器的快速失败行为,因为一般来说,在存在非同步并发修改的情况下不可能做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的正确性的程序是错误的:快速失败迭代器应该只用于检测错误。

此类是 Java 集合框架 的成员。

实现注意事项:

这是一个简单的linear-probe哈希表,例如在 Sedgewick 和 Knuth 的文章中描述的。该数组包含交替的键和值,键在偶数索引处,值在奇数索引处。 (对于大型表,这种安排比使用单独的数组具有更好的局部性。)对于许多 Java 实现和操作混合,此类将产生比 HashMap 更好的性能,后者使用chaining而不是线性探测。

自从:
1.4
参见:
  • 构造方法详细信息

    • IdentityHashMap

      public IdentityHashMap()
      使用默认的预期最大大小 (21) 构造一个新的空身份hash map。
    • IdentityHashMap

      public IdentityHashMap(int expectedMaxSize)
      构造一个具有指定预期最大大小的新空map。将超过预期数量的键值映射放入map中可能会导致内部数据结构增长,这可能会有些耗时。
      参数:
      expectedMaxSize - map的预期最大尺寸
      抛出:
      IllegalArgumentException - 如果 expectedMaxSize 为负
    • IdentityHashMap

      public IdentityHashMap(Map <? extends K ,? extends V > m)
      构造一个新的标识hash map,其中包含指定map中的键值映射。
      参数:
      m - 要将其映射放置到此map中的映射
      抛出:
      NullPointerException - 如果指定的map为空
  • 方法详情

    • size

      public int size()
      返回此标识hash map中键值映射的数量。
      指定者:
      size 在接口 Map<K,V>
      重写:
      size 在类 AbstractMap<K,V>
      返回:
      此map中键值映射的数量
    • isEmpty

      public boolean isEmpty()
      如果此标识hash map不包含键值映射,则返回 true
      指定者:
      isEmpty 在接口 Map<K,V>
      重写:
      isEmpty 在类 AbstractMap<K,V>
      返回:
      true 如果此标识hash map不包含键值映射
    • get

      public V  get(Object  key)
      返回指定键映射到的值,如果此map不包含键的映射,则返回 null

      更正式地说,如果此map包含从键 k 到值 v 的映射,使得 (key == k) ,则此方法返回 v ;否则返回 null 。 (最多可以有一个这样的映射。)

      null 的返回值不一定指示映射不包含键的映射;map也可能将密钥显式映射到 nullcontainsKey 操作可用于区分这两种情况。

      指定者:
      get 在接口 Map<K,V>
      重写:
      get 在类 AbstractMap<K,V>
      参数:
      key - 要返回其关联值的键
      返回:
      指定键映射到的值,如果此map不包含键的映射,则返回 null
      参见:
    • containsKey

      public boolean containsKey(Object  key)
      测试指定的对象引用是否是此标识hash map中的键。返回 true 当且仅当此map包含具有键 k 的映射使得 (key == k)
      指定者:
      containsKey 在接口 Map<K,V>
      重写:
      containsKey 在类 AbstractMap<K,V>
      参数:
      key - 可能的关键
      返回:
      true 如果指定的对象引用是此map中的键
      参见:
    • containsValue

      public boolean containsValue(Object  value)
      测试指定的对象引用是否是此标识hash map中的值。当且仅当此map包含值为 v 且满足 (value == v) 的映射时,才返回 true
      指定者:
      containsValue 在接口 Map<K,V>
      重写:
      containsValue 在类 AbstractMap<K,V>
      参数:
      value - 要测试其在此map中是否存在的值
      返回:
      true 如果此map将一个或多个键映射到指定的对象引用
      参见:
    • put

      public V  put(K  key, V  value)
      将指定值与此标识hash map中的指定键相关联。如果这个map已经contains 键的映射,旧值被替换,否则,一个新的映射被插入到这个map中。
      指定者:
      put 在接口 Map<K,V>
      重写:
      put 在类 AbstractMap<K,V>
      参数:
      key - 与指定值关联的键
      value - 要与指定键关联的值
      返回:
      key 关联的先前值,如果没有 key 的映射,则为 null 。 (返回 null 还可以指示之前将 nullkey 相关联的映射。)
      参见:
    • putAll

      public void putAll(Map <? extends K ,? extends V > m)
      将指定map中的所有映射复制到此map。对于指定map中的每个映射,如果此map已经contains 键的映射,则其值将替换为指定map中的值;否则,一个新的映射被插入到这个map中。
      指定者:
      putAll 在接口 Map<K,V>
      重写:
      putAll 在类 AbstractMap<K,V>
      参数:
      m - 要存储在此map中的映射
      抛出:
      NullPointerException - 如果指定的map为空
    • remove

      public V  remove(Object  key)
      从此map中删除此键的映射(如果存在)。当且仅当映射具有键 k 使得 (key == k) 时,映射才会被删除。
      指定者:
      remove 在接口 Map<K,V>
      重写:
      remove 在类 AbstractMap<K,V>
      参数:
      key - 要从map中删除其映射的键
      返回:
      key 关联的先前值,如果没有 key 的映射,则为 null 。 (返回 null 还可以指示之前将 nullkey 相关联的映射。)
    • clear

      public void clear()
      从此map中删除所有映射。此调用返回后map将为空。
      指定者:
      clear 在接口 Map<K,V>
      重写:
      clear 在类 AbstractMap<K,V>
    • equals

      public boolean equals(Object  o)
      比较指定对象与此map是否相等。如果给定对象也是一个映射并且两个映射表示相同的对象引用映射,则返回 true。更正式地说,这个map等于另一个map m 当且仅当 this.entrySet().equals(m.entrySet()) 。请参阅 entrySet 方法以了解此map条目的相等性规范。

      由于map基于引用相等性的语义,如果将map与普通map进行比较,可能会违反 Object.equals 契约的对称性和传递性要求。然而,Object.equals 合约保证在 IdentityHashMap 个实例中持有。

      指定者:
      equals 在接口 Map<K,V>
      重写:
      equals 在类 AbstractMap<K,V>
      参数:
      o - 要与此map进行相等比较的对象
      返回:
      true 如果指定的对象等于这个map
      参见:
    • hashCode

      public int hashCode()
      返回此map的哈希码值。映射的哈希码定义为该map的每个条目的哈希码之和。请参阅 entrySet 方法以了解此map条目的哈希码规范。

      此规范确保 m1.equals(m2) 暗示 m1.hashCode()==m2.hashCode() 对于任何两个 IdentityHashMap 实例 m1m2,正如 Object.hashCode() 的总合同所要求的那样。

      由于此map的 entrySet 方法返回的集合中 Map.Entry 实例的基于引用相等性的语义,如果要比较的两个对象之一是IdentityHashMap实例,另一个是普通map。

      指定者:
      hashCode 在接口 Map<K,V>
      重写:
      hashCode 在类 AbstractMap<K,V>
      返回:
      此map的哈希码值
      参见:
    • clone

      public Object  clone()
      返回此身份hash map的浅表副本:键和值本身未被克隆。
      重写:
      clone 在类 AbstractMap<K,V>
      返回:
      这张map的浅表副本
      参见:
    • keySet

      public Set <K > keySet()
      返回此map中包含的键的基于身份的集合视图。该集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map,则迭代的结果是不确定的。该集合支持元素删除,即通过 Iterator.removeSet.removeremoveAllretainAllclear 方法从map中删除相应的映射。它不支持 addaddAll 方法。

      虽然此方法返回的对象实现了 Set 接口,但它确实not遵守Set's总合同。与其支持map一样,此方法返回的集合将元素相等性定义为引用相等性而不是对象相等性。这会影响其 containsremovecontainsAllequalshashCode 方法的行为。

      仅当指定对象是包含与返回集完全相同的对象引用的集时,返回集的 equals 方法才返回 true。如果将此方法返回的集合与普通集合进行比较,则可能会违反 Object.equals 合约的对称性和传递性要求。但是,保证 Object.equals 合同在此方法返回的集合中持有。

      返回集的hashCode方法返回的总和身份哈希码集合中元素的总和,而不是它们哈希码的总和。这是由 equals 方法的语义变化强制执行的,以便在该方法返回的集合中强制执行 Object.hashCode 方法的一般契约。

      指定者:
      keySet 在接口 Map<K,V>
      重写:
      keySet 在类 AbstractMap<K,V>
      返回:
      此map中包含的键的基于身份的集合视图
      参见:
    • values

      public Collection <V > values()
      返回此map中包含的值的 Collection 视图。集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map,则迭代的结果是不确定的。该集合支持元素删除,即通过 Iterator.removeCollection.removeremoveAllretainAllclear 方法从map中删除相应的映射。它不支持 addaddAll 方法。

      虽然此方法返回的对象实现了 Collection 接口,但它确实not遵守Collection's总合同。与其支持map一样,此方法返回的集合将元素相等性定义为引用相等性而不是对象相等性。这会影响其 containsremovecontainsAll 方法的行为。

      指定者:
      values 在接口 Map<K,V>
      重写:
      values 在类 AbstractMap<K,V>
      返回:
      此map中包含的值的集合视图
    • entrySet

      public Set <Map.Entry <K ,V >> entrySet()
      返回此map中包含的映射的 Set 视图。返回集中的每个元素都是基于引用相等性的 Map.Entry 。该集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map,则迭代的结果是不确定的。该集合支持元素删除,即通过 Iterator.removeSet.removeremoveAllretainAllclear 方法从map中删除相应的映射。它不支持 addaddAll 方法。

      与支持map一样,此方法返回的集合中的 Map.Entry 对象将键和值相等定义为引用相等而不是对象相等。这会影响这些 Map.Entry 对象的 equalshashCode 方法的行为。当且仅当 oMap.Entrye.getKey()==o.getKey() && e.getValue()==o.getValue() 时,基于引用相等性的 Map.Entry e 等于对象 o。为了适应这些等号语义,hashCode 方法返回 System.identityHashCode(e.getKey()) ^ System.identityHashCode(e.getValue())。 (虽然使用引用相等性比较键和值,但 Map.Entry 对象本身不是。)

      由于此方法返回的集合中 Map.Entry 实例的基于引用相等性的语义,如果将集合中的任何条目与正常条目进行比较,则可能违反 Object.equals(Object) 合约的对称性和传递性要求贴图条目,或者如果将此方法返回的集合与一组普通map条目进行比较(例如在普通map上调用此方法将返回)。但是,Object.equals 合约保证在基于身份的映射条目之间以及此类条目的集合中持有。

      指定者:
      entrySet 在接口 Map<K,V>
      返回:
      此map中包含的身份映射的集合视图
    • remove

      public boolean remove(Object  key, Object  value)
      仅当指定键当前映射到指定值时才删除该条目。

      更正式地说,如果此map包含从键 k 到值 v 的映射,例如 (key == k)(value == v) ,则此方法删除此键的映射并返回 true ;否则返回 false

      指定者:
      remove 在接口 Map<K,V>
      参数:
      key - 与指定值关联的键
      value - 预期与指定键关联的值
      返回:
      true 如果值被删除
    • replace

      public boolean replace(K  key, V  oldValue, V  newValue)
      仅当当前映射到指定值时才替换指定键的条目。

      更正式地说,如果此map包含从键 k 到值 v 的映射,例如 (key == k)(oldValue == v) ,则此方法将 knewValue 关联并返回 true ;否则返回 false

      指定者:
      replace 在接口 Map<K,V>
      参数:
      key - 与指定值关联的键
      oldValue - 预期与指定键关联的值
      newValue - 与指定键关联的值
      返回:
      true 如果值被替换