必须重写hashCode()以满足equals与hashCode的一致性契约:参与equals比较的字段须全部参与hashCode计算,推荐用Objects.hash(),避免可变字段,子类重写时需确保父类hashCode已正确实现。

因为 Java 规范强制要求:如果两个对象 equals() 返回 true,它们的 hashCode() 必须返回相同值。这不是建议,而是哈希类集合(如 HashMap、HashSet)能正常工作的底层契约。
哈希容器靠 hashCode 定位,再用 equals 确认
当你把自定义对象作为 key 放进 HashMap,或加入 HashSet 时:
- JVM 先调用
hashCode(),算出它该存到哪个“桶”(数组索引) - 只在那个桶里,才逐个调用
equals()判断是否真正相等 - 如果没重写
hashCode(),逻辑上相等的对象(比如 id 相同的两个User)可能散列到不同桶中——后续get()或contains()就永远找不到
不重写 hashCode 的典型故障现象
这些不是编译错误,而是运行时静默失效:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
HashSet.add(a)和add(b)都成功,即使a.equals(b) == true→ 集合出现重复元素 -
map.put(key1, value)成功,但map.get(key2)返回null,尽管key1.equals(key2) -
new HashSet(list)去重失败,而list.stream().distinct()却正常
怎么写才算合格
核心原则只有一条:参与 equals 比较的字段,必须全部参与 hashCode 计算。
立即学习“Java免费学习笔记(深入)”;
- 推荐用
Objects.hash(f1, f2, f3),自动处理null和类型转换 - 避免使用可变字段(比如后期会修改的
status),否则对象入集合后再改字段,哈希值变化 → 永远取不出来 - 如果
equals()只比id,hashCode()就只用id;如果还加了name和email,哈希计算也得包含这三个
继承场景下容易被忽略的一点
子类重写 equals() 时,若引入新字段,不仅自己要重写 hashCode(),还要确保父类的 hashCode() 已正确实现。否则父子对象之间可能违反对称性或一致性契约。

















