IdentityHashMap 使用 == 比较键的内存地址而非 equals(),实现物理相等语义;适用于调试、对象身份缓存等场景,性能略高但不支持内容查找。

IdentityHashMap 在 Java 中通过 == 运算符 比较键(和值)的内存地址,而不是调用 equals() 方法。这意味着即使两个对象逻辑上相等(equals() 返回 true),只要它们不是同一个对象实例(即不同内存地址),在 IdentityHashMap 中就被视为不同的键。
为什么用 == 而不是 equals()
普通 HashMap 使用 hashCode() 和 equals() 判断键是否重复;而 IdentityHashMap 绕过这些方法,直接比较引用是否指向同一块堆内存。这适用于需要“物理相等”语义的场景,比如:
- 避免因重写
equals()导致的意外覆盖(如调试工具、序列化中间状态) - 缓存基于对象身份而非内容(例如:为每个对象实例单独记录元数据)
- 处理不可变但
equals()行为复杂的类(如某些代理对象或自定义类未正确实现equals())
基本用法示例
下面代码演示相同内容但不同实例的对象,在 IdentityHashMap 中被当作不同键:
IdentityHashMap<String, Integer> map = new IdentityHashMap<>();
String a = new String("hello");
String b = new String("hello");
map.put(a, 100);
map.put(b, 200);
System.out.println(map.size()); // 输出 2
System.out.println(map.get(a)); // 100
System.out.println(map.get(b)); // 200
System.out.println(map.get("hello")); // null(字面量字符串不在 map 中)
注意:"hello" 是字符串常量池中的对象,与 a、b 内存地址不同,所以查不到。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
与 HashMap 的关键区别
-
HashMap:键重复判断依赖hashCode()+equals(),适合业务逻辑相等性 -
IdentityHashMap:只看引用是否相同(a == b),性能略高(省去方法调用),但语义更严格 - 两者都不允许
null键重复(但IdentityHashMap允许一个null键,因为null == null为true)
使用注意事项
IdentityHashMap 不是线程安全的,多线程环境下需手动同步;它也不保证迭代顺序(底层用哈希表,但不维护插入顺序);另外,它不支持基于内容的查找——你必须持有原始引用才能取值。
如果后续需要按内容查找,应改用 HashMap 或配合其他结构(如额外维护一个内容到引用的映射)。

















