讲师中心 微信公众号
AI工具推荐 视频效率加速

在Java里集合中对象相等性如何判断_Javaequals与hashCode解析

夏敏大大_9750

夏敏大大_9750

发布时间:2026-01-23 03:57:18

|

951人浏览过

|

来源于php中文网

原创

是的。equals()不重写时默认用==比较内存地址,导致逻辑相等的对象被视为不等;必须同时重写hashCode()以保证哈希集合正确查找,且二者参与比较的字段须严格一致。

在java里集合中对象相等性如何判断_javaequals与hashcode解析

equals() 方法不重写就等于 == 吗?

是的。Java 中所有类默认继承自 Object,其 equals() 方法底层就是用 == 比较两个引用是否指向同一内存地址。这意味着:即使两个 Person 对象字段值完全相同,只要不是同一个实例,equals() 就返回 false。

常见错误现象:

  • 往 HashSet 或 HashMap 里添加自定义对象后查不到 —— 因为没重写 equals() 和 hashCode()
  • list.contains(new Person("Alice", 25)) 总是返回 false,哪怕列表里已有相同字段的对象

实操建议:

  • 只要类会被用于集合查找、去重、作为 Map 键,就必须重写 equals()
  • 重写时只比较业务上“逻辑相等”的字段(比如 id 或 username),不要包含可变字段(如 lastLoginTime)
  • 务必先用 == 判断是否为同一引用,再判 null,最后用 Objects.equals() 比较字段 —— 避免 NPE

为什么重写了 equals() 还必须重写 hashCode()?

因为哈希集合(HashSet、HashMap 的 key)依赖 hashCode() 快速定位桶位置。如果两个对象 equals() 返回 true,但 hashCode() 不同,它们会被散列到不同桶中,导致“明明存在却查不到”。

立即学习“Java免费学习笔记(深入)”;

违反约定的后果:

Java注释规范Skills
Java注释规范Skills

当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。

下载
  • HashSet.add(obj) 可能重复添加逻辑相等的对象
  • map.get(key) 返回 null,即使该 key 已存在
  • JVM 不报错,但行为不可预测 —— 这是最难调试的一类 bug

实操建议:

  • 用 Objects.hash(field1, field2, ...) 生成 hashCode(),它自动处理 null
  • 参与 hashCode() 计算的字段,必须和 equals() 中比较的字段严格一致
  • 避免在 hashCode() 中使用可变字段(如普通 setter 修改的属性),否则对象加入集合后修改字段会导致哈希码变化,再也找不回来

IDE 自动生成的 equals/hashCode 安全吗?

IntelliJ / Eclipse 生成的代码基本可用,但有三个关键点容易被忽略:

  • 默认会把所有非静态字段都纳入比较和哈希计算 —— 如果类里有 transient 字段、缓存字段或懒加载代理(如 Hibernate 的 LazyInitializationException 相关字段),必须手动剔除
  • 若字段是集合(如 List<string></string>),生成的 Objects.equals() 调用是安全的;但若字段是自定义对象,且该对象没重写 equals(),整个链路仍会失效
  • 生成的 hashCode() 使用 Objects.hash() 是对的,但要注意:如果字段本身重写了 hashCode(),要确认其实现是否稳定(比如是否依赖运行时状态)

示例:一个典型的安全重写片段

public class User {
    private final String username;
    private final int age;
    private transient String cacheToken; // 不参与 equals/hashCode

    @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(username, user.username);
    }

    @Override
    public int hashCode() {
        return Objects.hash(username, age); // 不含 cacheToken
    }
}

String、Integer 等包装类为什么可以直接用?

因为 JDK 已经为它们正确实现了 equals() 和 hashCode():比较的是值而非引用,且哈希值由值唯一确定。但要注意边界情况:

  • new String("abc").equals("abc") 是 true,但 new String("abc") == "abc" 是 false
  • Integer 在 [-128, 127] 范围内会缓存,所以 Integer.valueOf(100) == Integer.valueOf(100) 成立;超出范围则不一定
  • 永远别用 == 比较两个 Integer 是否“值相等”,必须用 .equals()

复杂点在于:一旦你组合这些类型(比如 Map<string list>></string>),只要嵌套结构里的每一层都满足契约,整个集合的行为就是可预期的。最容易被忽略的是——你自己写的类,哪怕只作为某个多层嵌套对象中的一个字段,也必须守规矩。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

相关专题

更多
eclipse教程
eclipse教程

php中文网为大家带来eclipse教程合集,eclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。php中文网还为大家带来eclipse的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

690

2023.06.14

eclipse怎么设置中文
eclipse怎么设置中文

eclipse设置中文的方法:除了设置界面为中文外,你还可以为Eclipse添加中文插件,以便更好地支持中文编程。例如,你可以安装EBNF插件来支持中文变量名,或安装Chinese Helper来提供中文帮助文档。本专题为大家提供eclipse设置中文相关的各种文章、以及下载和课程。

5766

2023.07.24

c语言编程软件有哪些
c语言编程软件有哪些

c语言编程软件有GCC、Clang、Microsoft Visual Studio、Eclipse、NetBeans、Dev-C++、Code::Blocks、KDevelop、Sublime Text和Atom。更多关于c语言编程软件的问题详情请看本专题的文章。php中文网欢迎大家前来学习。

8939

2023.11.02

Eclipse版本号有哪些区别
Eclipse版本号有哪些区别

区别:1、Eclipse 3.x系列:Eclipse的早期版本,包括3.0、3.1、3.2等;2、Eclipse 4.x系列:Eclipse的最新版本,包括4.0、4.1、4.2等;3、Eclipse IDE for Java Developers等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2804

2024.02.23

eclipse和idea有什么区别
eclipse和idea有什么区别

eclipse和idea的区别:1、平台支持;2、内存占用;3、插件系统;4、智能代码提示;5、界面设计;6、调试功能;7、学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

662

2024.02.23

eclipse设置中文全教程
eclipse设置中文全教程

本专题整合了eclipse设置中文相关教程,阅读专题下面的文章了解更多详细操作。

3726

2025.10.10

eclipse字体放大教程
eclipse字体放大教程

本专题整合了eclipse字体放大教程,阅读专题下面的文章了解更多详细内容。

3745

2025.10.10

eclipse左边栏不见了解决方法
eclipse左边栏不见了解决方法

本专题整合了eclipse左边栏相关教程,阅读专题下面的文章了解更多详细内容。

508

2025.10.15

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

20

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn