IdentityHashMap 通过 == 比较 key 的内存地址而非 equals(),哈希值用 System.identityHashCode() 计算;适用于需区分内容相同但不同实例的场景,如 new String("abc") 创建的多个字符串。

IdentityHashMap 在 Java 中就是专门通过对象的内存地址(即引用相等性,==)来判断 key 是否相等,而不是调用 equals() 方法。这是它和 HashMap 最核心的区别。
底层比较逻辑:用 == 而非 equals()
当你向 IdentityHashMap 插入或查找 key 时,它内部使用的是:
-
key1 == key2判断两个 key 是否指向同一块内存地址 - 完全忽略
key1.equals(key2)的结果,哪怕你重写了equals()也没用 - 哈希值也通过
System.identityHashCode()计算,而非obj.hashCode()
典型使用场景:需要区分“内容相同但不同实例”的 key
比如你有多个内容相同的字符串或自定义对象,但希望它们作为不同的 key 存在:
- String 字符串字面量会走常量池,所以
"abc" == "abc"为 true;但用new String("abc")创建的就不是同一个对象 - 自定义类即使重写了
equals()和hashCode(),在IdentityHashMap中仍按实例区分
代码示例对比
以下代码能清晰体现差异:
立即学习“Java免费学习笔记(深入)”;
String s1 = new String("hello");
String s2 = new String("hello");
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put(s1, 100);
System.out.println(hashMap.get(s2)); // 输出 100(因为 s1.equals(s2) == true)
Map<String, Integer> identityMap = new IdentityHashMap<>();
identityMap.put(s1, 100);
System.out.println(identityMap.get(s2)); // 输出 null(因为 s1 != s2)
注意事项
- 不要把
IdentityHashMap当作常规 Map 使用,除非你明确需要基于引用的语义 - 它不遵循
Map接口的一般约定(比如containsKey行为与equals()无关),某些框架可能不兼容 - 线程不安全,如需并发使用,应配合
Collections.synchronizedMap()或改用其他方案


















