Java 中的 IdentityHashMap 类

2025年5月8日 | 阅读 8 分钟

IdentityHashMap 类与 HashMap 类类似。它实现了 AbstractMap 类。然而,它在比较键(或值)时使用引用相等性,而不是对象相等性。

它不是 Map 的通用实现。虽然此类实现了 Map 接口,但它有意违反了 Map 的通用约定,该约定要求在比较对象时使用 equals() 方法。

它专门设计用于需要引用相等性语义的罕见情况。当用户需要使用引用来比较对象时,它被使用。

我们需要导入 java.util 包才能使用 IdentityHashMap 类。

IdentityHashMap 的特点

  • 它使用引用相等性,而不是使用 equals() 方法。它使用 == 运算符。
  • 必须在外部同步 IdentityHashMap,因为它之前未同步。
  • 迭代器在尝试在迭代期间修改时会抛出 ConcurrentModificationException
  • 假设 System.identityHashCode(Object) 正确地将元素分散在存储桶中,它为 get 和 put 等基本操作提供了恒定的时间性能。IdentityHashMap 不使用 hashCode() 方法,而是使用 System.identityHashCode() 方法。这是一个显著的区别,因为现在您可以使用可变对象作为 Map 的键,这些对象的哈希码在映射存储在 IdentityHashMap 中时可能会更改。

语法

其中,K 是 Object 类型的键,V 是 Object 类型的值。

IdentityHashMap 的构造函数

有两种方法可以创建 IdentityHashMap 实例

1. IdentityHashMap()

它创建一个新的空身份哈希映射,默认的预期最大大小为 21。

语法

2. IdentityHashMap(int ExpectedMaxSize)

它创建一个新的空身份哈希映射,具有给定的指定预期最大大小。

语法

3. IdentityHashMap(Map m)

它创建一个新的身份哈希映射,其中包含指定映射中的键值对。

语法

IdentityHashMap 类的所有方法

除了从其父类继承的方法外,IdentityHashMap 还定义了以下方法

序号。方法描述
1.void clear()它清除映射,即删除所有映射。
2.Set entrySet()它返回映射中键值对的 set 视图。
3.Set keySet()它返回哈希映射中包含的键的基于引用的 set 视图。
4.Object put (Object key, Object value)它将给定的值与给定的键关联在身份哈希映射中。
5.void putAll (Map t)它将指定映射(在参数中)中的所有映射复制到当前映射。这些映射将替换当前映射中任何现有键的映射。
6.Object remove (Object key)它从映射中删除指定键的所有映射(如果存在)。
7.int size()它返回身份哈希映射中的键值对数量。
8.Object clone()它返回给定身份哈希映射的浅拷贝。但是,键和值不会被克隆。
9.boolean containsKey (Object key)它检查指定的对象是否是给定身份哈希映射中的一个键。
10.boolean containsValue (Object value)它检查指定的对象引用是否是给定身份哈希映射中的一个值。
11.boolean equals (Object o)它将指定对象与映射进行比较以检查相等性。
12.Object get (Object key)它返回给定键在身份哈希映射中映射到的值。如果映射不包含该键的映射,则返回 null。
13.int hashCode()它返回映射的哈希码值。
14.boolean isEmpty()如果指定的身份哈希映射不包含任何映射,则返回 true。
15.Collection values()它返回映射中值 collection 视图。

让我们使用 IdentityHashMap 类的所有方法。

IdentityHashMapDemo.java

输出

IdentityHashMap Class in Java

IdentityHashMap 上的基本操作

1. 添加元素

要将元素添加到 IdentityHashMap 中,我们需要使用 put() 和 putAll() 方法。put() 方法将指定的键和值映射到映射中。当传入当前键时,旧值将被新值替换。putAll() 方法将一个映射中的所有键值映射复制到另一个映射。

示例

让我们考虑以下示例,其中我们在 Java 程序中实现 put() 和 putAll() 方法。

IdentityHashMapExample1.java

输出

IdentityHashMap Class in Java

2. 删除元素

要从映射中删除映射(键值对),我们使用 remove() 方法。

让我们考虑以下示例,其中我们在 Java 程序中使用 remove() 方法删除一个映射。

IdentityHashMapExample2.java

输出

IdentityHashMap Class in Java

3. 访问元素

要访问 IdentityHashMap 的元素,我们使用 get() 方法。

让我们考虑以下示例,其中我们使用 get() 方法从映射中访问映射。

IdentityHashMapExample3.java

输出

IdentityHashMap Class in Java

4. 遍历 IdentityHashMap

要遍历 Collection Framework 的所有结构,我们使用 Iterator 接口。由于迭代器仅处理单一类型的数据,我们使用 Entry以兼容的格式解决两种不同的类型。然后我们将使用 next() 方法打印 IdentityHashMap 的元素。

IdentityHashMapExample4.java

输出

IdentityHashMap Class in Java

IdentityHashMap 和 HashMap 之间的区别

  • IdentityHashMap 使用相等运算符 (==) 来比较键和值,而 HashMap 使用 equals() 方法在 Map 中比较键和值。
  • 由于 IdentityHashMap 不使用 equals() 方法,因此它比 HashMap 更快。
  • IdentityHashMap 不需要键是不可变的,因为它不依赖于 equals()。

以下示例解释了 IdentityHashMap 和 HashMap 类之间的区别。

IdentityHashMapVSHashMap.java

输出

IdentityHashMap Class in Java

同步的 IdentityHashMap

当多个线程并发访问身份哈希映射,并且至少一个线程对映射进行了结构性修改时,有必要在外部同步该映射。(映射的结构性修改是指添加或删除一个或多个键值映射。如果仅更改实例中已包含的键关联的值,则不是结构性修改。)

这可以通过同步任何封装该映射的对象来实现。如果不存在这样的对象,则应使用 Collections.synchronizedMap() 方法将映射 **包装** 起来。执行此操作的正确时间是在创建时,以防止对映射进行不同步访问。

语法

其中 K 是映射中键的类型,V 是与之映射的值的类型。