先说结论

== 比较基本类型的值,比较引用类型时判断是否指向同一对象。equals 默认与 == 相同,但值对象通常会重写它。hashCode 为哈希容器提供桶定位依据。

equals 与 hashCode 契约

两个对象 equals 相等,它们的 hashCode 必须相等;hashCode 相等,equals 不一定相等。重写 equals 时必须同时重写 hashCode。

常见错误

只重写 equals 会导致逻辑上相等的对象进入 HashSet 后仍然重复,或者无法从 HashMap 中正确取回。

HashMap 为什么同时需要两者

查询时先用 hashCode 定位桶,再用 equals 确认具体键。哈希只是缩小范围,不是相等性的最终判断。只重写 equals 会让逻辑相等的对象落入不同桶,导致 get 失败或 HashSet 出现重复。

常见问题

追问 1:hashCode 相同,equals 一定为 true 吗?

不一定。哈希空间有限,碰撞必然存在,所以命中桶后必须继续比较 equals

追问 2:为什么不建议用可变对象作为键?

若参与哈希计算的字段在插入后变化,新哈希位置与原桶不一致,即使对象仍在 Map 中也可能无法查询和删除。

追问 3:BigDecimal 比较有什么陷阱?

1.01.00 使用 compareTo 数值相等,但 equals 还比较精度。金额逻辑必须明确需要数值相等还是严格对象相等。