在 Java 中,`==` 和 `equals()` 的区别

✅ Java 中 ==equals()hashCode()

在 Java 中,==equals() 的区别主要体现在 引用类型 上:


🔹 ==

  • 用于 基本数据类型intdoubleboolean 等)时,比较的是 值是否相等
  • 用于 引用类型 时,比较的是 两个引用是否指向同一个对象(内存地址是否相同)

🔹 equals()

  • Object 类中定义的方法
  • 如果 没有被重写 ,默认实现与 == 相同,比较的也是 引用地址
  • 在实际开发中,如果需要判断两个对象是否 逻辑相等(内容相等) ,通常会 重写 equals() 方法
  • 重写时一般使用 Objects.equals(a, b),以避免字段为 null 时出现 空指针异常

🔹 hashCode()equals() 的关系

  • 重写 equals() 的同时,必须重写 hashCode()

  • 因为在 HashMapHashSet 等哈希容器中:

    • 先通过 hashCode() 计算哈希值,定位存储位置(桶)
    • 再通过 equals() 判断对象是否真正相等
  • 为了保证哈希容器行为正确,必须满足:

    • equals() 相等的对象,hashCode() 必须相等
    • hashCode() 相等的对象,equals() 不一定相等

🔹 作为 HashMap / HashSet 的 key 的注意事项(真实开发重点)

  • 参与 equals()hashCode() 的字段 应尽量是不可变的
  • 不建议使用 会被修改的字段(如状态、余额、时间等)
  • 否则可能导致对象 put 进容器后,修改字段,再 get找不到对应的对象

🔹 多字段对象如何实现 equals / hashCode

  • 不要求使用所有字段

  • 一般选择:

    • id
    • 业务唯一键
  • 这些字段能唯一标识一个业务对象即可

  • 常见实现方式:

    java 复制代码
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

🔹 Lombok 在实际开发中的使用(面试加分点)

  • 在实际项目中,通常会使用 Lombok 自动生成 equals()hashCode(),以减少手写错误

  • 常见写法:

    java 复制代码
    @EqualsAndHashCode(onlyExplicitlyIncluded = true)
    public class User {
    
        @EqualsAndHashCode.Include
        private Long id;
    
        private String name;
        private String email;
    }
  • 这样可以明确指定哪些字段参与比较,更安全、更易维护


🔹 Java 已经重写好的常用类

  • Java 中一些常用类(如 StringIntegerLong 等)

    • 已经重写了 equals()hashCode() 方法
    • 用于比较对象的 内容是否相等
  • 自定义实体类在参与比较,或作为 HashMap / HashSet 的 key 时,通常需要 手动重写或使用 Lombok 生成


🧠 一句话面试总结

在 Java 中,== 用于比较基本类型的值或引用地址;
equals() 用于判断对象的逻辑相等;

重写 equals() 时必须同时重写 hashCode(),并且参与比较的字段应尽量是不可变的;

实际项目中通常使用 Lombok 来生成 equals()hashCode(),以减少人为错误。


相关推荐
oak隔壁找我8 小时前
JVM常用调优参数
java·后端
蝎子莱莱爱打怪12 小时前
OpenClaw 从零配置指南:接入飞书 + 常用命令 + 原理图解
java·后端·ai编程
狼爷13 小时前
Go 没有 override?别硬套继承!用接口+嵌入,写更清爽的“覆盖”逻辑
java·go
小兔崽子去哪了16 小时前
Java 自动化部署
java·后端
ma_king16 小时前
入门 java 和 数据库
java·数据库·后端
后端AI实验室16 小时前
我用Cursor开发了3个月,整理出这套提效4倍的工作流
java·ai
码路飞20 小时前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
SimonKing21 小时前
OpenCode AI编程助手如何添加Skills,优化项目!
java·后端·程序员
Seven971 天前
剑指offer-80、⼆叉树中和为某⼀值的路径(二)
java
怒放吧德德1 天前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty