在Java里为什么HashSet必须同时重写equals和hashCode_Java集合一致性说明
发布时间 - 2026-01-31 00:00:00 点击率:次HashSet查找失败的根本原因是hashCode()与equals()未同步重写:只重equals()导致哈希值不同而散列到不同桶,只重hashCode()则因equals()未重写仍判为不等且性能退化为O(n),正确做法是二者同时重写并保持逻辑一致。
HashSet查找失败的根本原因
因为HashSet内部用HashMap实现,元素存储位置由hashCode()决定,而判断是否重复依赖equals()。两者不一致时,对象可能被放进错误的桶(bucket),导致contains()返回false,即使逻辑上相等的对象已存在。
只重写equals()会出什么问题
新对象hashCode()仍走Object默认实现(基于内存地址),哪怕两个对象equals()返回true,它们的哈希值也大概率不同,会被散列到不同桶中。结果就是:
-
set.add(obj1)成功 -
set.contains(obj2)返回false(尽
管
obj1.equals(obj2) == true) -
set.size()可能大于预期(重复对象未被去重)
只重写hashCode()又会怎样
所有对象哈希值相同(比如都返回1),全部挤进同一个桶,HashSet退化为链表遍历,性能从O(1)掉到O(n);更严重的是,若equals()没重写,两个本该相等的对象仍被视为不同——因为Object.equals()比较的是引用,不是内容。
典型表现:
- 插入多个字段相同的对象,
size()持续增长 -
iterator里能看到“重复”元素 - 用
stream().distinct()处理这类集合也无效
正确重写模板与关键约束
必须同时满足:相等的对象有相同哈希值;哈希值相同的对象不一定相等(允许碰撞,但不宜过多)。
public class User {
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age); // 顺序、字段必须和equals保持一致
}
}
注意:
-
Objects.hash()是安全选择,手动计算需确保null安全(如name == null ? 0 : name.hashCode()) - 参与
hashCode()计算的字段,必须全部出现在equals()的比较逻辑中 - 一旦对象加入
HashSet,就不应修改影响hashCode()或equals()的字段——否则该对象可能永远无法被remove()或contains()命中
HashSet后还去修改name或age这种关键字段。这时候它在哈希表里的位置就“失效”了,既找不到也删不掉。
# java
# ai
# stream
# 为什么
# Object
# NULL
# 对象
# 重写
# 的是
# 根本原因
# 多个
# 找不到
# 出现在
# 遍历
# 这类
# 不应
# 又会
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel中的withCount方法怎么高效统计关联模型数量
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信
Laravel如何实现一对一模型关联?(Eloquent示例)
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
免费视频制作网站,更新又快又好的免费电影网站?
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
如何获取上海专业网站定制建站电话?
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
Laravel怎么使用Intervention Image库处理图片上传和缩放
Linux网络带宽限制_tc配置实践解析【教程】
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Laravel如何创建自定义中间件?(Middleware代码示例)
Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
如何快速上传自定义模板至建站之星?
高防服务器:AI智能防御DDoS攻击与数据安全保障
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
Laravel Fortify是什么,和Jetstream有什么关系
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
怎样使用JSON进行数据交换_它有什么限制
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
移动端脚本框架Hammer.js
常州企业网站制作公司,全国继续教育网怎么登录?
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】
Laravel怎么判断请求类型_Laravel Request isMethod用法
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
Android Socket接口实现即时通讯实例代码
JavaScript如何实现类型判断_typeof和instanceof有什么区别
如何用好域名打造高点击率的自主建站?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
个人摄影网站制作流程,摄影爱好者都去什么网站?
iOS发送验证码倒计时应用
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
JavaScript如何实现错误处理_try...catch如何捕获异常?
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
Laravel如何使用模型观察者?(Observer代码示例)
网站制作软件免费下载安装,有哪些免费下载的软件网站?
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
焦点电影公司作品,电影焦点结局是什么?


