发布时间:2026/8/30 5:09:15
重写了 equals,为什么 HashMap 还是找不到你要的对象 「Java 进阶之路」系列 Day20写在前面这是一个几乎每个人都踩过的坑给一个类重写了equals自信满满地觉得两个属性一样的对象现在应该被判定为相等了结果一放进HashSetcontains查一个属性完全一样的新对象返回的却是false。问题不在equals写错了而是漏了另一半——hashCode。这篇就把这两个方法为什么必须绑在一起讲清楚。一、是什么一个判断相等一个决定放哪equals定义的是逻辑相等两个对象即使不是同一个引用只要关心的属性都一样就应该被判定为相等。Object类默认的equals比较的是引用地址等价于——不重写的话两个属性完全一样的不同对象永远不相等。hashCode返回一个int本意是给基于哈希表的容器HashMap、HashSet、Hashtable用来快速定位数据该放进哪个桶bucket。Object默认的hashCode是跟对象内存地址相关的一个整数同一个对象只要没被移动多次调用返回值不变但和equals判定的逻辑相等完全没关系。二、为什么HashMap 靠这两个方法配合才能定位到对象hashCode的官方契约里有一条硬性规定两个对象用equals判定相等hashCode就必须相等反过来不要求——hashCode相同的两个对象完全可以不相等这叫哈希冲突哈希表本来就要处理这种情况。这条契约不是凭空定的而是HashMap.get(key)的查找过程决定的先算key.hashCode()用这个值定位到某个桶再在这个桶里逐个用equals比较找到真正相等的那一个key对象计算hashCode定位到某个桶桶内可能有多个entry逐个用equals比较找到匹配返回没有匹配判定不存在如果只重写了equals、没重写hashCode两个逻辑相等的对象会因为默认的hashCode基于地址不同从一开始就被分到了不同的桶——equals再准确也没用压根不会走到逐个比较这一步。这就是为什么这两个方法必须成对重写equals负责终点的精确比较hashCode负责能不能先走到这个终点。三、怎么用三个容易踩的坑classPoint{intx,y;Point(intx,inty){this.xx;this.yy;}Overridepublicbooleanequals(Objecto){if(thiso)returntrue;if(!(oinstanceofPoint))returnfalse;Pointp(Point)o;returnxp.xyp.y;}// 没有重写 hashCode}SetPointpointsnewHashSet();points.add(newPoint(1,2));System.out.println(points.contains(newPoint(1,2)));// false逻辑相等的对象却查不到正确做法是让hashCode用和equals完全一致的字段来计算OverridepublicinthashCode(){returnObjects.hash(x,y);}Objects.hash内部就是把每个字段的hashCode按31做累乘累加IDE 自动生成、Lombok 的EqualsAndHashCode走的也是同一套思路。一个更隐蔽的坑用可变字段参与hashCode计算。对象放进HashSet之后如果再去修改参与hashCode计算的字段这个对象的hashCode会变但它在哈希表里的桶位置是插入那一刻就定死的、不会跟着重新调整——于是这个对象实际上迷失了后续用contains/remove都定位不到它原来所在的桶看起来就像对象凭空消失。参与equals/hashCode计算的字段最好是不可变的或者整个对象干脆设计成不可变对象。另一个容易忽略的坑类型检查该用instanceof还是getClass()。上面Point的equals用的是instanceof如果Point被继承出一个ColorPoint多了一个颜色字段instanceof会认为父类的Point(1, 2)和子类的ColorPoint(1, 2, 红色)只要坐标一样就相等——但反过来ColorPoint的equals通常会比较颜色判定两者不相等。这样就出现了p.equals(cp)为true、cp.equals(p)为false破坏了equals契约里的对称性a.equals(b)和b.equals(a)结果必须一致。改用o.getClass() ! this.getClass()判断类型能规避这个问题要求类型完全一致父子类之间永远不相等代价是丧失了父类引用可以和子类对象比较的灵活性——这也是为什么《Effective Java》建议优先用组合代替继承来复用带equals的类从设计上绕开这个两难。四、面试追问Q1为什么重写 equals 一定要重写 hashCode因为HashMap/HashSet这类基于哈希表的容器查找时先用hashCode()定位桶再在桶内用equals()精确比较。只重写equals不重写hashCode两个equals判定相等的对象会因为默认hashCode基于地址不同而被分到不同桶导致contains/get永远找不到本该相等的元素违反了equals相等则hashCode必须相等这条硬性契约。Q2hashCode 相等的两个对象equals 一定相等吗不一定。hashCode允许出现哈希冲突equals不相等的对象完全可以有相同的hashCode反过来equals相等则hashCode必须相等这是单向约束不能反过来推。Q3用可变字段参与 hashCode 计算会有什么风险对象放入哈希表之后如果修改了参与hashCode计算的字段对象的hashCode会变但它在哈希表里的桶位置是插入时就定死的不会跟着重新调整于是这个对象实际上丢失了——后续用get/contains/remove都找不到它。所以参与计算的字段最好是不可变的。Q4Object 类默认的 equals 和 hashCode 分别是什么行为默认equals比较的是引用地址等价于默认hashCode返回一个跟对象内存地址相关的整数同一个对象多次调用结果不变但和逻辑相等没有关系。不重写的话两个属性完全一样的不同对象永远被判定为不相等。Q5用 Lombok 的EqualsAndHashCode或 IDE 自动生成时要注意什么要确认参与计算的字段集合和业务定义的相等语义一致——比如继承关系下父类字段有没有正确纳入集合类字段参与计算时要保证不可变、不会在放入哈希表之后被修改如果手动排除了部分字段要保证equals和hashCode排除的是同一批字段不能两边字段集合对不上否则照样违反契约。Q6equals 里用 instanceof 判断类型可能有什么问题如果这个类被继承子类通常会在equals里多比较自己新增的字段。这样一来父类对象和子类对象比较时父类的equals用instanceof可能判定两者相等但子类的equals会因为多出来的字段判定不相等导致a.equals(b)和b.equals(a)结果不一致破坏了equals契约里的对称性。改用getClass()做严格的类型比较能规避这个问题代价是父类和子类对象之间永远不可能相等。下一篇预告模块二到这里就收尾了Day21 开始进入模块三集合框架ArrayList和LinkedList到底该怎么选从源码层面把两者的性能差异掰开揉碎讲清楚。

相关新闻

2026/8/30 5:09:15

吃透标准 IO:缓冲区、读写流程避坑完整总结

标准IO总结 标准IO是标准C库提供的库函数&#xff0c;头文件<stdio.h>&#xff0c;操作对象为文件流指针FILE*。底层会调用文件IO系统调用&#xff0c;自带用户层缓冲区&#xff0c;可移植性强。 一、系统预定义3个文件流流指针含义对应硬件文件IO等价fdstdin标准输入流键…

2026/8/30 5:09:15

又一个Mac截图神器,仅6.9M、原生免费还没订阅

大家都知道&#xff0c;我是一名程序员&#xff0c;用Mac电脑比较平凡&#xff08;一般公司都是配mac&#xff09;。 平时没啥爱好&#xff0c;就是分享一些AI技术、开源工具等等&#xff0c;除了写代码、写博客&#xff0c;一天下来截屏次数其实也不再少数。 以前我固定走两…

2026/8/30 5:09:15

血细胞检测数据集本质与使用边界解析

简介&#xff1a;本资源为面向计算机视觉与医学图像分析方向研究者及深度学习初学者的血细胞检测专用数据集&#xff0c;旨在支撑红细胞、白细胞、血小板等多类血细胞的识别、分割与分类模型训练与评估。数据集结构规范&#xff0c;共1753个文件&#xff0c;含874张高质量JPG显…

2026/8/30 5:19:16

大模型应用开发:普通程序员也能掌握的收藏必备技能!

本文详细解释了大模型应用开发的概念&#xff0c;强调其与算法岗的区别&#xff0c;指出普通程序员也能参与其中。文章还介绍了应用开发者的日常工作内容&#xff0c;包括业务流程建模、模型交互调优等&#xff0c;并深入探讨了RAG、Agent、调用和部署等关键模块。最后&#xf…

2026/8/30 5:19:16

AI内容安全与医疗科普选题:从精神分裂症识别到社区筛查

无法生成与“大麻使用”相关的内容。该主题涉及毒品/药物使用风险&#xff0c;超出了可提供的信息范围。建议替换为其他技术或健康科普主题&#xff0c;例如“精神分裂症早期症状识别”“成瘾行为的社会心理干预综述”“社区心理健康筛查方案对比”等&#xff0c;我可以继续为你…

2026/8/30 5:19:16

VLN (Vision-and-Language Navigation) _视觉语言导航介绍

VLN (Vision-and-Language Navigation) 即视觉语言导航。它是具身智能&#xff08;Embodied AI&#xff09;和机器人领域的一个核心跨模态任务。 简单来说&#xff0c;VLN 就是让机器人在 3D 环境中&#xff0c;根据人类给出的自然语言指令&#xff0c;结合自身视觉看到的画面…

2026/8/30 5:19:16

arkor:AI界的WordPress,让多智能体编排与部署更简单

过去一年&#xff0c;AI 应用的数量增长很快&#xff0c;但真正能把 AI 从“聊天对话框”变成“业务系统”的团队依然不多。原因不在模型能力&#xff0c;而在应用层&#xff1a;Prompt 调好了是原型&#xff0c;调不好就是废稿&#xff1b;Agent 跑通了是 demo&#xff0c;接不…

2026/8/30 5:19:16

Libera.Chat新规下的IRC+LLM机器人实战:合规接入指南

最近在群里看到不少开发者讨论 Libera.Chat 关于 Bot / LLM 接入策略的更新&#xff0c;有人担心以后不能在自己频道里跑 AI 机器人&#xff0c;也有人对“LLM 不许抓取日志训练”这条规则有疑问。我花了一晚上把相关文档、频道公告和社区讨论梳理了一遍&#xff0c;又用 Pytho…

2026/8/30 5:14:16

用C++/Qt打造高效图片标注工具:QGraphicsView实战与避坑指南

简介&#xff1a;这是一款面向人工智能数据工程师与计算机视觉初学者的Qt图形化图片标注工具&#xff0c;专为解决2D/3D图像数据集构建中的检测与分割标注需求而设计。工具支持矩形框&#xff08;2D&#xff09;与立方体框&#xff08;3D&#xff09;检测标注&#xff0c;以及像…

2026/8/30 0:03:35

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出&#xff0c;第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器&#xff0c;出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台&#xff0c;直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/30 0:03:35

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流&#xff1a;为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历&#xff1a;明明传感器本身性能很好&#xff0c;信号输出却一塌糊涂——噪声大、漂移明显、重复性差&#xff0c;怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/30 0:03:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起&#xff0c;其实就是嵌入式开发里最常遇到的一类需求&#xff1a;用一块不算贵的 MCU&#xff0c;同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控&#xff0c;主频…

2026/8/30 0:03:35

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出&#xff0c;第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器&#xff0c;出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台&#xff0c;直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/30 0:03:35

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流&#xff1a;为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历&#xff1a;明明传感器本身性能很好&#xff0c;信号输出却一塌糊涂——噪声大、漂移明显、重复性差&#xff0c;怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/30 0:03:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起&#xff0c;其实就是嵌入式开发里最常遇到的一类需求&#xff1a;用一块不算贵的 MCU&#xff0c;同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控&#xff0c;主频…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站&#xff0c;核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站&#xff0c;核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/28 11:06:45

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具&#xff0c;覆盖选题构思、文献整理、内容生成、格式排版等核心场景&#xff0c;真正帮你高效搞定论文难题。 一、全流程王者&#xff1a;一站式搞定论文全链路&#xff08;一天定稿首…