identityhashmap 使用==比较键引用和system.identityhashcode()计算哈希,适用于按对象身份而非语义映射的场景,如线程上下文缓存、对象图遍历防循环、调试对象生命周期跟踪。

IdentityHashMap 不使用 equals() 和 hashCode(),而是直接用对象的内存地址(即 ==)来判断键是否相等、计算哈希位置。
底层比较逻辑:用 == 替代 equals
普通 HashMap 在插入或查找时,会调用键对象的 equals() 方法判断两个键是否“逻辑相等”。而 IdentityHashMap 完全跳过该逻辑,只比较引用是否指向同一块内存:
- 两个键对象即使内容相同、
equals()返回true,只要不是同一个对象实例(即a != b),就被视为不同键; - 如果两个变量引用的是同一个对象(如
obj1 == obj2),哪怕它们重写了equals()返回false,也被认为是相同键。
哈希计算:用 System.identityHashCode()
它不调用对象自身的 hashCode() 方法,而是使用 System.identityHashCode(obj) —— 这个值基于对象内存地址生成,且在对象生命周期内保持不变(即使重写了 hashCode()):
- 避免因业务类误改
hashCode()导致哈希表失效; - 保证同一对象无论是否重写方法,其哈希码始终稳定。
典型适用场景
这种设计适用于需要“按对象身份而非语义”做映射的场合:
- 缓存内部状态(比如为每个线程对象单独记录上下文);
- 实现对象图遍历时避免循环引用(如序列化/反序列化中的对象引用跟踪);
- 调试工具中记录对象生命周期,区分“看似相同但实际不同的实例”。
注意事项
它不是为了替代 HashMap 的通用方案:
- 字符串字面量会因字符串常量池导致意外行为(
"abc" == "abc"为true); - 自动装箱的数值类型(如
Integer)在 [-128, 127] 范围内可能被缓存,造成非预期的引用相等; - 不能用于需要逻辑相等语义的业务键(例如用户 ID、订单号等应以内容为准)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











