Java IdentityHashMap类的用法 | baeldung


在本教程中,我们将学习如何在 Java中使用IdentityHashMap类。我们还将研究它与一般的HashMap类有何不同。虽然这个类实现了Map接口,但它违反了Map接口的约定。
IdentityHashMap类。
Java IdentityHashMap类实现了Map接口。Map接口强制要求在键的比较上使用equals()方法。然而,IdentityHashMap类违反了这个契约。相反,它在键的搜索操作上使用引用相等(==)。
在搜索操作中,HashMap使用hashCode()方法进行哈希散列,而IdentityHashMap使用System.identHashCode()方法。它还使用了哈希图的线性探测技术进行搜索操作。

引用相等、System.identityHashCode()和线性探测技术的使用使IdentityHashMap类具有更好的性能。

使用代码:

IdentityHashMap<String, String> identityHashMap = new IdentityHashMap<>();
identityHashMap.put("title", "Harry Potter and the Goblet of Fire");
identityHashMap.put(
"author", "J. K. Rowling");
identityHashMap.put(
"language", "English");
identityHashMap.put(
"genre", "Fantasy");

String value = identityHashMap.get(key);


我们也有不同的方法可用,其工作原理与其他地图对象类似。

  • clear(): 删除所有条目
  • containsKey(): 查找一个键是否存在于地图中,根据引用是否等同。
  • containsValue(): 查找值是否存在于地图中,根据引用是否等同。
  • keySet():返回一个基于identity的键集。
  • size(): 返回条目的数量
  • values():返回一个值的集合

 
IdentityHashMap并不是线程安全的,和HashMap一样。因此,如果我们有多个线程并行地访问/修改IdentityHashMap条目,我们应该将它们转换为同步map。

我们可以使用Collections类得到一个同步map。

Map<String, String> synchronizedMap = Collections.synchronizedMap(new IdentityHashMap<String, String>());


 
IdentityHashMap在equals()方法上使用引用是否相等(==)来搜索/存储/访问密钥对象。

HashMap<String, String> hashMap = new HashMap<>(identityHashMap);
hashMap.put(new String("genre"), "Drama");
assertEquals(4, hashMap.size());

当使用一个新的字符串对象 "genre "作为键时,HashMap将其等同于现有的键并更新其值。因此,Map的大小仍然是4。

下面的代码片断显示了IdentityHashMap的不同:

identityHashMap.put(new String("genre"), "Drama");
assertEquals(5, identityHashMap.size());

IdentityHashMap认为新的 "genre "字符串对象是一个新的键。
因此,它断定大小为5。两个不同的 "genre "对象被用作两个键。
 
 
IdentityHashMap允许可变键。这是该类的另一个有用的特性。

这里我们将把一个简单的Book类作为一个可变的对象。

class Book {
    String title;
    int year;
    
    // other methods including equals, hashCode and toString
}

首先,创建了两个Book类的可变对象。
Book book1 = new Book("A Passage to India", 1924);
Book book2 = new Book(
"Invisible Man", 1953);

下面是 IdentityHashMap:

IdentityHashMap<Book, String> identityHashMap = new IdentityHashMap<>(10);
identityHashMap.put(book1, "A great work of fiction");
identityHashMap.put(book2,
"won the US National Book Award");
book2.year = 1951;
assertEquals(
"won the US National Book Award", identityHashMap.get(book2));

即使键对象被修改,IdentityHashMap也能检索到值。在上面的代码中,assertEquals确保再次检索到相同的文本。由于引用是相等的,这是有可能的。
 
它对构建特定的框架很有帮助,包括。

  • 为一组易变的对象维护代理对象
  • 基于一个对象的引用建立一个快速缓存
  • 保持一个有引用的对象的内存图