在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 】
相关推荐:
简单实现jsp分页
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
如何在建站宝盒中设置产品搜索功能?
php结合redis实现高并发下的抢购、秒杀功能的实例
Laravel如何使用Passport实现OAuth2?(完整配置步骤)
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】
Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】
Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】
Java遍历集合的三种方式
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法
Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作
Laravel如何使用Livewire构建动态组件?(入门代码)
Angular 表单中正确绑定输入值以确保提交与验证正常工作
Laravel如何为API编写文档_Laravel API文档生成与维护方法
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
如何用IIS7快速搭建并优化网站站点?
PHP 500报错的快速解决方法
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
如何用AI帮你把自己的生活经历写成一个有趣的故事?
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】
如何在阿里云高效完成企业建站全流程?
如何在阿里云购买域名并搭建网站?
python中快速进行多个字符替换的方法小结
SQL查询语句优化的实用方法总结
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
如何在腾讯云免费申请建站?
iOS中将个别页面强制横屏其他页面竖屏
实例解析angularjs的filter过滤器
制作企业网站建设方案,怎样建设一个公司网站?
如何在新浪SAE免费搭建个人博客?
Laravel如何使用Collections进行数据处理?(实用方法示例)
原生JS获取元素集合的子元素宽度实例
如何快速登录WAP自助建站平台?
BootStrap整体框架之基础布局组件
Laravel如何处理文件下载请求?(Response示例)
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
如何快速使用云服务器搭建个人网站?
Python结构化数据采集_字段抽取解析【教程】
南京网站制作费用,南京远驱官方网站?
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?


