新闻详情

新闻详情

首页 / 资讯中心 / 详情

Java中equals方法比了个寂寞?原来这才是正确的重写姿势

发布时间:2026/9/28 20:56:42来源:尧图网络
Java中equals方法比了个寂寞?原来这才是正确的重写姿势
去年在金融项目里处理一笔对账数据时我们突然发现系统漏掉了300多条记录——明明两个Transaction对象的金额和账户ID完全一致HashSet.contains()却始终返回false。排查到最后问题竟然出在一个看似简单的equals方法上。你是不是也以为重写equals就是比较几个字段今天咱们就聊聊那些年equals方法里藏过的坑。当equals遇上HashSet一个对账系统的惨案我们的对账模块需要比对两个数据源的交易记录逻辑很简单用HashSet存储基准数据然后遍历待核对数据调用contains()比对。在测试环境一切正常但生产环境跑完总有漏网之鱼。 通过日志最终锁定问题某些Transaction对象虽然业务字段值相同但hashCode()返回值却不一样——因为有人偷懒只重写了equals却忘了hashCode。这里有个硬规则如果两个对象equals返回true它们的hashCode必须相同。否则当对象作为键存入HashMap或HashSet时会存在哈希桶定位错误的风险。// 错误示范只重写equals Override public boolean equals(Object o) { if (this o) return true; if (o null || getClass() ! o.getClass()) return false; Transaction that (Transaction) o; return amount.equals(that.amount) accountId.equals(that.accountId); } // 正确姿势必须配套重写hashCode Override public int hashCode() { return Objects.hash(amount, accountId); // 使用相同字段 }为什么Lombok的EqualsAndHashCode也翻过车你可能会说我用Lombok自动生成不就完了别急去年另一个坑正出在这里。某次上线后监控突然显示某个核心服务CPU飙到90%堆栈显示卡在HashMap.get()——因为自动生成的hashCode()包含了全部字段而其中一个字段是BLOB类型的大文本关键点hashCode()必须满足一致性对象不变时返回值不变但不要求所有字段参与运算。对于重型字段应该手动排除EqualsAndHashCode(onlyExplicitlyIncluded true) public class Order { EqualsAndHashCode.Include private Long id; // 只使用轻量级字段 private byte[] pdfContent; // 排除大字段 }实测对比包含10KB文本字段的类调用hashCode()耗时从1200ns降至60nsJMH基准测试预热后结果。谁杀死了你的equals性能假设你给用户权限系统写了这样的equals// 性能杀手无谓的字符串比对 Override public boolean equals(Object o) { //...省略判空 User user (User) o; return username.equals(user.username) permissions.stream() .sorted() .collect(joining(,)) .equals(user.permissions.stream() .sorted() .collect(joining(,))); }问题出在每次比较都要对流进行排序和拼接。如果权限列表有20项单次equals耗时直接突破1ms实测数据。对于高频调用的场景这种写法就是自杀。优化原则优先比较大概率不等的字段避免深层嵌套结构的完全遍历return username.equals(user.username) permissions.size() user.permissions.size() permissions.containsAll(user.permissions); // 前提是Set实现避坑清单equals重写的军规hashCode必须和equals同步重写违反这条直接导致HashMap/HashSet行为异常避免可变字段参与计算如果参与equals的字段会被修改对象作为Map键时将失踪数组字段用Arrays.equals比较直接调用array.equals()比较的是引用浮点数字段用Double.compare处理NaN和±0.0等特殊情况子类equals必须满足里氏替换原则子类新增字段会导致对称性被破坏终极答案什么时候才该重写equals经过这些年踩坑我的判断标准只有两条需要对象逻辑相等而非引用相等时比如值对象确定该对象会作为集合元素或Map键使用时否则直接使用Object的默认实现反而是最安全的选择。你在项目里遇到过哪些equals的奇葩坑欢迎分享你的血泪史。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Agent-Native应用架构实战:从概念到落地的关键设计 2026/9/28 23:38:59

Agent-Native应用架构实战:从概念到落地的关键设计

“agent-native”这个词最近在圈子里讨论度很高,我一开始以为是营销话术,毕竟“AI原生”“大模型驱动”这类概念这两年见得太多。直到自己动手把两个项目从“带AI的普通应用”重构为“以智能体为核心的应用”,踩了一堆文档里没写的坑&#xf…

阅读更多 →
中文NER模型实战:HMM/CRF/BiLSTM+CRF的Python实现与选型指南 2026/9/28 23:38:59

中文NER模型实战:HMM/CRF/BiLSTM+CRF的Python实现与选型指南

简介:这套面向中文命名实体识别(NER)任务的Python资源包,集成了HMM、CRF、BiLSTM、BiLSTMCRF等经典模型的完整实现,并配有包含人名、地名、机构名及“其它”类别的标注数据集。数据标签基于B/M/E位置标记形成10种类别&…

阅读更多 →
鱼鹰算法优化XGBoost:Matlab分类工程实战与调参指南 2026/9/28 23:38:59

鱼鹰算法优化XGBoost:Matlab分类工程实战与调参指南

简介:本资源面向计算机、电子信息工程、数学等专业的大学生及算法初学者,提供一套基于鱼鹰优化算法(OOA)优化XGBoost的分类预测完整方案,可用于课程设计、期末大作业与毕业设计。压缩包共18个文件,约53.69M…

阅读更多 →
SSM知识产权管理系统毕设实战指南 2026/9/28 23:38:59

SSM知识产权管理系统毕设实战指南

简介:这是一套面向计算机专业本科生的知识产权管理系统毕业设计源码,基于SSM(SpringSpringMVCMyBatis)框架开发,完整覆盖前后端功能与数据库设计,适用于Java课程设计、毕设选题及Web开发能力实训。资源共10…

阅读更多 →
Codex CLI 安装配置与 401 报错排查实战指南 2026/9/28 23:38:53

Codex CLI 安装配置与 401 报错排查实战指南

1. 从一次深夜报错说起:Codex 安装到底卡在哪如果你最近在折腾 Codex CLI,大概率经历过这样的场景:装完之后兴冲冲敲下第一条命令,终端直接甩回来一句unexpected status 401 unauthorized: missing bearer or basic authenticatio…

阅读更多 →
agent-native实战拆解:从核心架构到落地避坑 2026/9/28 23:38:53

agent-native实战拆解:从核心架构到落地避坑

“agent-native”这个词,最近在圈子里出现的频率高到让人没法忽视。我第一次认真琢磨它,是因为团队吵着要给一个内部运营系统“接Agent”,结果大家讨论了一周才发现,对“Agent到底该干什么”几乎没有共识。有人觉得是加个聊天入口…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉