在Java中为什么要重写equals和hashCode_equals与hashCode设计规范解析
发布时间 - 2025-12-31 00:00:00 点击率:次必须重写equals和hashCode以保证逻辑相等对象在HashMap等集合中行为一致:若equals为true则hashCode必相同;二者需遵守自反性、对称性、传递性、一致性及null处理约定,且字段选择须合理。
在Java中重写 equals 和 hashCode,核心原因只有一个:**保证对象逻辑相等时,行为一致且能正确工作于基于哈希的集合(如 HashMap、HashSet)中**。不重写,或重写不合规,会导致“明明两个对象内容一样,却查不到”“同一个对象存了两份”等诡异问题。
equals 与 hashCode 必须保持一致性
这是最根本的设计契约:如果两个对象通过 equals 判断为 true,那么它们的 hashCode 值必须相同;反之则不要求(不同对象可以有相同哈希值,即哈希碰撞)。JDK 的集合类(如 HashMap)正是依赖这一约定工作的:先用 hashCode 快速定位桶位置,再用 equals 精确比对键值。
- 只重写
equals不重写hashCode→ 逻辑相等的对象可能被散列到不同桶,get()或contains()失败 - 只重写
hashCode不重写equals→ 即使哈希值相同,equals默认比较引用,仍判为不等,集合操作仍出错 - 两者都重写但逻辑不一致(例如
equals比较 name+age,hashCode只用 name 计算)→ 违反契约,行为不可预测
重写 equals 要遵守五项基本约定
equals 方法不是随便写的,它必须满足自反性、对称性、传递性、一致性,以及对 null 的处理。违反任一约定,可能引发 HashSet 重复、TreeSet 异常、甚至并发场景下死循环等严重问题。
-
自反性:对任意非 null 引用
x,x.equals(x)必须返回true -
对称性:若
x.equals(y)为true,则y.equals(x)也必须为true -
传递性:若
x.equals(y)且y.equals(z)为true,则x.equals(z)必须为true - 一致性:多次调用结果不变(前提是没有修改影响比较的字段)
-
对 null 的处理:对任意非 null 引用
x,x.equals(null)必须返回false
实践中,推荐使用 Objects.equals(a, b) 安全比较字段,避免空指针;用 instanceof + 类型强转做类型检查,而非 getClass() == obj.getClass()(除非明确要求严格类型限制)。
hashCode 的实现要兼顾分布性与确定性
hashCode 不必唯一,但应尽量让逻辑不同的对象产生不同哈希值(减少碰撞),更重要的是:只要参与比较的字段没变,多次调用必须返回相同值。常见写法是使用 Objects.hash(field1, field2, ...),它自动处理 null 并组合字段哈希。
- 不要在
hashCode中使用可变字段(如普通 setter 修改的属性),否则对象加入HashSet后再修改字段,就再也找不到了 - 不要用随机数、当前时间、内存地址等不确定值参与计算
- 若类是不可变的(如
String、自定义的Point),用所有关键字段参与哈希计算最稳妥
IDE 和 Lombok 可以帮你生成,但得懂原理
IntelliJ 或 Eclipse 都支持自动生成 equals 和 hashCode 方法,Lombok 的 @EqualsAndHashCode 更是只需一行注解。但生成只是起点——你仍需确认:选了哪些字段?是否包含父类字段?是否忽略某些业务
上不该参与比较的字段(如数据库主键 ID、创建时间)?
- 默认生成通常包含所有非静态字段,可能过度(比如含临时缓存字段)
- 若继承自某个父类,且父类已重写
equals/hashCode,子类生成时应调用super.equals()和super.hashCode() - Lombok 的
callSuper = true或exclude = {"id"}等参数要按需配置
不复杂但容易忽略。
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
python中快速进行多个字符替换的方法小结
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
大型企业网站制作流程,做网站需要注册公司吗?
Laravel如何实现API版本控制_Laravel API版本化路由设计策略
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
,在苏州找工作,上哪个网站比较好?
*服务器网站为何频现安全漏洞?
Laravel中的Facade(门面)到底是什么原理
Python文件操作最佳实践_稳定性说明【指导】
高端建站如何打造兼具美学与转化的品牌官网?
如何在IIS7中新建站点?详细步骤解析
青岛网站建设如何选择本地服务器?
详解jQuery停止动画——stop()方法的使用
制作公司内部网站有哪些,内网如何建网站?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
Firefox Developer Edition开发者版本入口
如何快速建站并高效导出源代码?
php增删改查怎么学_零基础入门php数据库操作必知基础【教程】
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
LinuxCD持续部署教程_自动发布与回滚机制
网站制作企业,网站的banner和导航栏是指什么?
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
HTML 中动态设置元素 name 属性的正确语法详解
微信小程序 HTTPS报错整理常见问题及解决方案
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
JavaScript Ajax实现异步通信
北京网站制作的公司有哪些,北京白云观官方网站?
简历在线制作网站免费版,如何创建个人简历?
高端建站三要素:定制模板、企业官网与响应式设计优化
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
如何用PHP工具快速搭建高效网站?
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
Laravel如何使用Livewire构建动态组件?(入门代码)
Swift中switch语句区间和元组模式匹配
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
JavaScript如何实现音频处理_Web Audio API如何工作?
如何在云指建站中生成FTP站点?
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
如何解决hover在ie6中的兼容性问题
高性能网站服务器部署指南:稳定运行与安全配置优化方案
如何在云服务器上快速搭建个人网站?
,交易猫的商品怎么发布到网站上去?

