必须同时重写 equals 和 hashcode,否则 hashmap/hashset 行为异常;equals 需满足自反性、对称性、传递性、一致性、非空性;hashcode 必须包含 equals 中所有比较字段,推荐用 objects.hash() 生成。

必须一起重写,不能只改一个。只重写 equals 而不重写 hashCode,对象放进 HashMap 或 HashSet 就会“找不到”或“重复存入”,不是 Bug,是契约被破坏了。
先写 equals,再生成 hashCode
手写容易漏字段或逻辑错位,建议用 IDE(如 IntelliJ)自动生成:
– 先完整实现 equals,确保它只基于业务上真正决定“相等性”的字段;
– 然后右键 → Generate → hashCode and equals,勾选**完全相同的字段**;
– 别手动删掉某个字段的参与——哪怕它暂时为 null,只要 equals 里用了,hashCode 就得算。
equals 方法要满足五个基本规则
否则集合行为不可靠:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 自反性:自己和自己比,必须返回
true - 对称性:
a.equals(b)和b.equals(a)结果一致 - 传递性:若
a.equals(b)且b.equals(c),则a.equals(c)也得成立 - 一致性:只要参与比较的字段没变,多次调用结果不能变
- 非空性:
obj.equals(null)必须返回false,不能抛空指针
hashCode 的计算要和 equals 严格对齐
核心原则就一条:所有在 equals 中用于判断相等的字段,必须全部参与 hashCode 计算。
- 推荐用
Objects.hash(f1, f2, f3),安全、简洁、自动处理 null - 避免在
hashCode里调用可能改变状态的方法(比如带懒加载逻辑的 getter) - 不要用随机数、时间戳、数据库 ID(未赋值时为 0)这类不稳定值
- 如果字段是对象类型,优先用它的
hashCode();是基本类型,用对应包装类的hashCode(如Integer.hashCode(age))
别忘了加 @Override 和类型检查
防止签名写错或误覆写父类其他方法:
- 必须写
@Override注解,编译器能帮你拦截参数类型错误 - 用
getClass() == obj.getClass()做类型校验,不用instanceof(避免子类打破对称性) - 开头加
this == obj快速返回,提升性能 - 中间加
obj == null和类型判断,保证非空性和类型安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










