详细分析Java中的@EqualsAndHashCode基本知识(附Demo)

前言

🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF

基本的Java知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

1. 基本知识

@EqualsAndHashCode 是 Lombok 提供的一个注解,用于自动生成 equals() 和 hashCode() 方法。它的作用主要包括:

  • equals() 方法:用于比较两个对象是否相等(判断两个对象的属性值是否相等,而不仅仅是引用相等)
  • hashCode() 方法:用于生成对象的哈希值,保证相同对象的哈希值一致,以支持哈希集合(如 HashSet、HashMap)的正常工作

实战中的运用过程如下:

在这里插入图片描述

callSuper = true 代表在生成 equals() 和 hashCode() 方法时,会调用父类的 equals() 和 hashCode() 方法

这在继承结构中很重要,确保父类的字段也参与比较

假设我们有如下的继承关系:

@Data
@EqualsAndHashCode
class Parent {
    private Long id;
}

@Data
@EqualsAndHashCode(callSuper = true)
class Child extends Parent {
    private String name;
}

等价于:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Child)) return false;
    if (!super.equals(o)) return false; // 关键点:调用父类的 equals()
    Child child = (Child) o;
    return Objects.equals(name, child.name);
}

@Override
public int hashCode() {
    return Objects.hash(super.hashCode(), name); // 关键点:调用父类的 hashCode()
}

可以看出:

  • 不加 callSuper = true:只比较 Child 类的 name 属性,父类 id 不参与计算
  • 加了 callSuper = true:id 也参与 equals() 和 hashCode() 计算,保证继承关系下对象的完整性

2. 实战

在结合上述实战知识点

@TableName("equipment_tyre_repare_order")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "TyreRepareOrder对象", description = "TyreRepareOrder对象")
public class TyreRepareOrder extends BaseEntity {

    private static final long serialVersionUID = 1L;
    
    private String orderId;
    private String tyreCode;
    private Integer status;
}

TyreRepareOrder 继承了 BaseEntity,如果 BaseEntity 里有 id、createTime、updateTime 等字段,callSuper = true 让这些字段也参与 equals() 和 hashCode() 计算

这样可以确保:

  • 避免 HashSet、HashMap 出现重复数据问题(两个对象如果 equals() 不一致,可能会导致集合中存入重复数据)
  • 在 Hibernate / MyBatis 等 ORM 框架中,正确判断对象是否已经存在(对象的相等性影响数据库操作)

什么时候需要 callSuper = true?

如果父类中有影响对象相等性的字段(如 id),建议加 callSuper = true。
如果子类完全独立,且不希望父类字段影响比较,可以省略 callSuper = true。

避免 Lombok 生成的 equals() 和 hashCode() 引起的 bug

@EqualsAndHashCode 默认会 比较所有字段,但在某些情况下,某些字段(如 transient 字段或数据库 auto-increment 的 id)不应该参与比较

@EqualsAndHashCode(exclude = "id")
public class Order {
    private Long id;  // 自增ID,不应该影响 equals
    private String orderNumber;
}

避免 hashCode() 方法中使用可变字段(如 List),否则对象放入 HashSet 后再修改字段,可能导致无法找到该对象

总的来说:

选项作用
@EqualsAndHashCode生成 equals() 和 hashCode()
@EqualsAndHashCode(callSuper = true)让父类的字段也参与 equals() 和 hashCode()
@EqualsAndHashCode(exclude = “id”)排除某些字段,不参与比较
@EqualsAndHashCode(onlyExplicitlyIncluded = true)仅包含 @EqualsAndHashCode.Include 注解的字段

实战中常用的位置如下:

  • 实体类(如数据库表映射):通常需要 @EqualsAndHashCode(callSuper = true),确保 id 参与计算,避免 ORM 误判对象是否已存在
  • DTO / VO 类:可以使用 @EqualsAndHashCode(onlyExplicitlyIncluded = true),手动指定哪些字段参与计算,避免无关字段影响对象比较
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值