应使用identityhashmap当需基于引用相等性(==)而非equals()判断键是否相等,例如对象图遍历中避免重复处理同一实例;其哈希值由system.identityhashcode()计算,put两个内容相同但不同的string实例会存为不同键,get时必须传入原对象引用才能命中。

IdentityHashMap 在 Java 中用于基于内存地址(即引用相等性,==)而非 equals() 方法来判断键是否相等。它适用于需要区分“逻辑相同但不同实例”的场景,比如在对象图遍历、序列化、代理处理或循环引用检测中避免重复处理同一对象实例。
什么时候该用 IdentityHashMap 而不是 HashMap
当你关心的是“是不是同一个对象”(即是否指向堆中同一块内存),而不是“内容是否一样”时,就该选 IdentityHashMap。例如:
- 两个
new String("hello")实例内容相同,但equals()返回true,==返回false;IdentityHashMap会把它们当作不同键。 - 在深度克隆或图遍历时,需记录“已处理过的对象引用”,防止无限递归——这时必须靠引用判等,不能依赖
equals()。
基本用法:声明、插入与查找
使用方式和 HashMap 类似,但内部比较逻辑完全不同:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
注意:它的 key 和 value 的哈希值仍通过 System.identityHashCode() 计算,不是 hashCode() 方法。
- 构造:
IdentityHashMap<string integer> map = new IdentityHashMap();</string> - 插入:
map.put(new String("a"), 1); map.put(new String("a"), 2);—— 这会存两条记录,因为是两个不同对象。 - 查找:
map.get(new String("a"))返回null,除非你传入当初 put 时的**同一个对象引用**。
典型应用场景示例
比如实现一个简单的对象遍历去重器(避免重复访问同一对象):
- 定义
IdentityHashMap<object boolean> visited = new IdentityHashMap();</object> - 每次访问前检查:
if (!visited.containsKey(obj)) { visited.put(obj, true); process(obj); } - 即使多个对象
equals()相同,只要不是同一个实例,就不会跳过。
注意事项和限制
IdentityHashMap 不是线程安全的,也不保证迭代顺序(底层是数组+链表,但扩容策略与 HashMap 不同)。另外:
- 它不遵循
Map接口的一般契约(比如containsKey行为依赖==而非equals),因此不能随意替换HashMap。 - 如果键对象重写了
hashCode(),对IdentityHashMap没影响;它始终调用System.identityHashCode()。 - 不要将
null作为 key 使用(虽然允许,但容易引发混淆,且identityHashCode(null)抛异常)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










