哈希值不是唯一标识,哈希冲突不可避免;因对象状态无穷而哈希值范围有限,不同对象可能产生相同hashcode,此时需依赖equals进一步判断相等性。

因为哈希值只是对象的一个“快速定位标签”,不是唯一身份标识。
哈希冲突是数学上不可避免的
哈希函数把任意长度的对象信息压缩成固定长度的整数(比如32位int),而对象可能有无穷多种状态,但int最多只有约42亿个不同取值。所以必然存在不同的对象算出相同的hashCode——这叫哈希碰撞(hash collision)。例如:
- String s1 = "Aa"; String s2 = "BB"; 它们的hashCode都是2112,但s1.equals(s2)为false
- Integer i1 = 100; Integer i2 = 100 + 0; 这两个对象内容相同,hashCode也相同,equals为true;但换一组不同内容的对象,也可能凑巧得到相同hashCode
HashMap等容器的设计就是容忍这种不唯一性
哈希表先用hashCode快速跳到某个桶(bucket),再在桶内用equals逐个比对。桶里可以放多个hashCode相同的对象,只要它们不真正相等就行。这就像快递柜:柜号(hashCode)只决定放在哪一排,但打开柜门后还得核对取件码(equals)才能确认是不是你的包裹。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
重写时若只看字段子集,也会导致hashCode相同但内容不同
比如Person类只用name和age算hashCode,但实际还有id、email等字段。两个Person对象name和age一样,hashCode就相同;但email不同,equals就返回false。这是设计使然,不是bug。
本质上,hashCode是效率优化手段,equals才是语义上真正的相等判断。两者分工明确:一个快但粗略,一个准但较慢。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










