- 类型参数:
K- 此map维护的键类型V- 映射值的类型
- 所有已实现的接口:
Serializable,Cloneable,Map<K,V>
Map 接口,在比较键(和值)时使用引用相等代替对象相等。换句话说,在 IdentityHashMap 中,当且仅当 (k1==k2) 时,两个键 k1 和 k2 被认为是相等的。 (在正常的 Map 实现中(如 HashMap )当且仅当 (k1==null ? k2==null : k1.equals(k2)) 时,两个键 k1 和 k2 被认为是相等的。)
这堂课是not一个通用的Map实现!虽然此类实现了 Map 接口,但它故意违反了 Map's 通用契约,该契约要求在比较对象时使用 equals 方法。此类旨在仅在需要引用相等语义的极少数情况下使用。
该map的视图集合的元素也具有引用相等语义。有关详细信息,请参阅 keySet 、values 和 entrySet 方法。
这个类的一个典型用途是拓扑保持对象图变换,例如序列化或深度复制。要执行这样的转换,程序必须维护一个“节点表”,用于跟踪所有已处理的对象引用。节点表不能使不同的对象相等,即使它们恰好相等。此类的另一个典型用途是维护代理对象.例如,调试工具可能希望为被调试程序中的每个对象维护一个代理对象。
此类提供所有可选的map操作,并允许 null 值和 null 键。此类不保证map的顺序;特别是,它不保证顺序会随着时间的推移保持不变。
此类为基本操作(get 和 put)提供恒定时间性能,假设系统身份哈希函数(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
- 参见:
-
内部类总结
在类 java.util.AbstractMap 中声明的嵌套类/接口
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K, V> -
构造方法总结
构造方法构造方法描述使用默认的预期最大大小 (21) 构造一个新的空身份hash map。IdentityHashMap(int expectedMaxSize) 构造一个具有指定预期最大大小的新空map。IdentityHashMap(Map<? extends K, ? extends V> m) 构造一个新的标识hash map,其中包含指定map中的键值映射。 -
方法总结
修饰符和类型方法描述voidclear()从此map中删除所有映射。clone()返回此身份hash map的浅表副本:键和值本身未被克隆。booleancontainsKey(Object key) 测试指定的对象引用是否是此标识hash map中的键。booleancontainsValue(Object value) 测试指定的对象引用是否是此标识hash map中的值。entrySet()返回此map中包含的映射的Set视图。boolean比较指定对象与此map是否相等。返回指定键映射到的值,如果此map不包含键的映射,则返回null。inthashCode()返回此map的哈希码值。booleanisEmpty()如果此标识hash map不包含键值映射,则返回true。keySet()返回此map中包含的键的基于身份的集合视图。将指定值与此标识hash map中的指定键相关联。void将指定map中的所有值复制到此map。从此map中删除此键的映射(如果存在)。boolean仅当指定键当前映射到指定值时才删除该条目。boolean仅当当前映射到指定值时才替换指定键的条目。intsize()返回此标识hash map中键值映射的数量。values()返回此map中包含的值的Collection视图。在类 java.util.AbstractMap 中声明的方法
toString在接口 java.util.Map 中声明的方法
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, replace, replaceAll
-
构造方法详细信息
-
IdentityHashMap
public IdentityHashMap()使用默认的预期最大大小 (21) 构造一个新的空身份hash map。 -
IdentityHashMap
public IdentityHashMap(int expectedMaxSize) 构造一个具有指定预期最大大小的新空map。将超过预期数量的键值映射放入map中可能会导致内部数据结构增长,这可能会有些耗时。- 参数:
expectedMaxSize- map的预期最大尺寸- 抛出:
IllegalArgumentException- 如果expectedMaxSize为负
-
IdentityHashMap
构造一个新的标识hash map,其中包含指定map中的键值映射。- 参数:
m- 要将其映射放置到此map中的映射- 抛出:
NullPointerException- 如果指定的map为空
-
-
方法详情
-
size
public int size()返回此标识hash map中键值映射的数量。 -
isEmpty
public boolean isEmpty()如果此标识hash map不包含键值映射,则返回true。 -
get
返回指定键映射到的值,如果此map不包含键的映射,则返回null。更正式地说,如果此map包含从键
k到值v的映射,使得(key == k),则此方法返回v;否则返回null。 (最多可以有一个这样的映射。)null的返回值不一定指示映射不包含键的映射;map也可能将密钥显式映射到null。containsKey操作可用于区分这两种情况。 -
containsKey
测试指定的对象引用是否是此标识hash map中的键。返回true当且仅当此map包含具有键k的映射使得(key == k)。- 指定者:
containsKey在接口Map<K,中V> - 重写:
containsKey在类AbstractMap<K,中V> - 参数:
key- 可能的关键- 返回:
true如果指定的对象引用是此map中的键- 参见:
-
containsValue
测试指定的对象引用是否是此标识hash map中的值。当且仅当此map包含值为v且满足(value == v)的映射时,才返回true。- 指定者:
containsValue在接口Map<K,中V> - 重写:
containsValue在类AbstractMap<K,中V> - 参数:
value- 要测试其在此map中是否存在的值- 返回:
true如果此map将一个或多个键映射到指定的对象引用- 参见:
-
put
将指定值与此标识hash map中的指定键相关联。如果这个map已经contains键的映射,旧值被替换,否则,一个新的映射被插入到这个map中。 -
putAll
将指定map中的所有映射复制到此map。对于指定map中的每个映射,如果此map已经contains键的映射,则其值将替换为指定map中的值;否则,一个新的映射被插入到这个map中。- 指定者:
putAll在接口Map<K,中V> - 重写:
putAll在类AbstractMap<K,中V> - 参数:
m- 要存储在此map中的映射- 抛出:
NullPointerException- 如果指定的map为空
-
remove
从此map中删除此键的映射(如果存在)。当且仅当映射具有键k使得 (key == k) 时,映射才会被删除。 -
clear
public void clear()从此map中删除所有映射。此调用返回后map将为空。 -
equals
比较指定对象与此map是否相等。如果给定对象也是一个映射并且两个映射表示相同的对象引用映射,则返回true。更正式地说,这个map等于另一个mapm当且仅当this.entrySet().equals(m.entrySet())。请参阅entrySet方法以了解此map条目的相等性规范。由于map基于引用相等性的语义,如果将map与普通map进行比较,可能会违反
Object.equals契约的对称性和传递性要求。然而,Object.equals合约保证在IdentityHashMap个实例中持有。 -
hashCode
public int hashCode()返回此map的哈希码值。映射的哈希码定义为该map的每个条目的哈希码之和。请参阅entrySet方法以了解此map条目的哈希码规范。此规范确保
m1.equals(m2)暗示m1.hashCode()==m2.hashCode()对于任何两个IdentityHashMap实例m1和m2,正如Object.hashCode()的总合同所要求的那样。由于此map的
entrySet方法返回的集合中Map.Entry实例的基于引用相等性的语义,如果要比较的两个对象之一是IdentityHashMap实例,另一个是普通map。 -
clone
返回此身份hash map的浅表副本:键和值本身未被克隆。- 重写:
clone在类AbstractMap<K,中V> - 返回:
- 这张map的浅表副本
- 参见:
-
keySet
返回此map中包含的键的基于身份的集合视图。该集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map,则迭代的结果是不确定的。该集合支持元素删除,即通过Iterator.remove、Set.remove、removeAll、retainAll和clear方法从map中删除相应的映射。它不支持add或addAll方法。虽然此方法返回的对象实现了
Set接口,但它确实not遵守Set's总合同。与其支持map一样,此方法返回的集合将元素相等性定义为引用相等性而不是对象相等性。这会影响其contains、remove、containsAll、equals和hashCode方法的行为。仅当指定对象是包含与返回集完全相同的对象引用的集时,返回集的
equals方法才返回true。如果将此方法返回的集合与普通集合进行比较,则可能会违反Object.equals合约的对称性和传递性要求。但是,保证Object.equals合同在此方法返回的集合中持有。返回集的
hashCode方法返回的总和身份哈希码集合中元素的总和,而不是它们哈希码的总和。这是由equals方法的语义变化强制执行的,以便在该方法返回的集合中强制执行Object.hashCode方法的一般契约。 -
values
返回此map中包含的值的Collection视图。集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map,则迭代的结果是不确定的。该集合支持元素删除,即通过Iterator.remove、Collection.remove、removeAll、retainAll和clear方法从map中删除相应的映射。它不支持add或addAll方法。虽然此方法返回的对象实现了
Collection接口,但它确实not遵守Collection's总合同。与其支持map一样,此方法返回的集合将元素相等性定义为引用相等性而不是对象相等性。这会影响其contains、remove和containsAll方法的行为。 -
entrySet
返回此map中包含的映射的Set视图。返回集中的每个元素都是基于引用相等性的Map.Entry。该集合由map支持,因此对map的更改会反映在集合中,反之亦然。如果在对集合进行迭代时修改map,则迭代的结果是不确定的。该集合支持元素删除,即通过Iterator.remove、Set.remove、removeAll、retainAll和clear方法从map中删除相应的映射。它不支持add或addAll方法。与支持map一样,此方法返回的集合中的
Map.Entry对象将键和值相等定义为引用相等而不是对象相等。这会影响这些Map.Entry对象的equals和hashCode方法的行为。当且仅当o是Map.Entry和e.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合约保证在基于身份的映射条目之间以及此类条目的集合中持有。 -
remove
仅当指定键当前映射到指定值时才删除该条目。更正式地说,如果此map包含从键
k到值v的映射,例如(key == k)和(value == v),则此方法删除此键的映射并返回true;否则返回false。 -
replace
仅当当前映射到指定值时才替换指定键的条目。更正式地说,如果此map包含从键
k到值v的映射,例如(key == k)和(oldValue == v),则此方法将k与newValue关联并返回true;否则返回false。
-