Lombok @EqualsAndHashCode 注解:简化对象比较

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/

截止目前, 星球 内专栏累计输出 66w+ 字,讲解图 2896+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2300+ 小伙伴加入学习 ,欢迎点击围观

Lombok 的 @EqualsAndHashCode 注解用于自动生成 equals()hashCode() 方法,这两个方法对于对象比较和在集合中的使用非常重要。equals() 方法决定了对象的比较方式,而 hashCode() 则影响对象在散列集合(如 HashSetHashMap)中的表现。

基本用法

默认情况下,@EqualsAndHashCode 会使用所有非静态字段来生成 equals()hashCode() 方法,这意味着两个对象在所有字段的值都相等时会被认为相等。

示例

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class User {
    private String name;
    private int age;
}

上面的代码会生成如下 equals()hashCode() 方法:

  • equals() 方法会逐个比较所有非静态字段的值。
  • hashCode() 方法则基于这些字段生成哈希码。

这样,当两个 User 对象的 nameage 值相同时,它们会被视为相等。

常用参数

@EqualsAndHashCode 提供了几个配置参数,允许自定义 equals()hashCode() 方法的生成方式。

exclude

exclude 参数用于指定不包含在 equals()hashCode() 方法中的字段。可以排除某些字段来避免它们影响比较结果。

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(exclude = "age")
public class User {
    private String name;
    private int age;
}

在这个示例中,age 字段不会被包含在 equals()hashCode() 方法中。因此,只要 name 字段的值相同,两个 User 对象就会被认为相等。

callSuper

callSuper 参数决定是否调用父类的 equals()hashCode() 方法。如果当前类继承了一个父类,并且希望在比较时将父类的字段也考虑在内,可以将 callSuper 设置为 true

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true)
public class Employee extends User {
    private String position;
}

callSupertrue 时,Employee 类的 equals()hashCode() 方法会首先调用 User 类的对应方法,然后再处理 Employee 自己的字段。

onlyExplicitlyIncluded

onlyExplicitlyIncluded 参数用于控制 equals()hashCode() 方法仅包含那些被 @EqualsAndHashCode.Include 标记的字段。可以通过该方式精确选择哪些字段用于比较。

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User {
    @EqualsAndHashCode.Include
    private String name;

    private int age; // 未添加 @EqualsAndHashCode.Include,不会影响 equals 和 hashCode
}

在这个例子中,age 字段不会包含在 equals()hashCode() 方法中。只有 name 字段会影响对象的比较结果。

注意事项

  • 排除可变字段:尽量避免使用可变字段(如集合、数组)作为 equals()hashCode() 的依据,以防止因值变化导致哈希码不一致的问题。
  • 继承关系:如果类涉及继承关系,并且希望子类对象在比较时包含父类的字段,建议设置 callSuper = true
  • 性能优化:在需要频繁比较或存储对象的场景下,合理地定制 equals()hashCode() 的字段可以提高性能。

小结

Lombok 的 @EqualsAndHashCode 注解通过自动生成 equals()hashCode() 方法,大大简化了对象比较的代码编写。通过使用 excludecallSuperonlyExplicitlyIncluded 参数,可以灵活控制哪些字段会影响对象的比较结果。