1. 为什么需要关注 equals 和 hashCode 方法?
在 Java 开发中,equals() 和 hashCode() 是两个基础但极其重要的方法。它们直接关系到对象在集合中的行为表现,特别是在使用 HashSet、HashMap 等基于哈希表的集合时。如果这两个方法实现不当,可能会导致:
- 集合无法正确识别相同的对象
- 对象存入集合后无法被正确查找
- 出现内存泄漏问题
- 程序性能下降
传统的手动实现方式不仅繁琐,而且容易出错。我曾经在一个项目中,因为忘记更新 hashCode() 方法导致线上出现严重的性能问题,排查了整整两天才发现是这个原因。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Lombok 的 @EqualsAndHashCode 基础用法
2.1 基本注解形式
最简单的使用方式就是在类上直接添加 @EqualsAndHashCode 注解:
java复制@EqualsAndHashCode
public class Product {
private Long id;
private String name;
private BigDecimal price;
}
编译后,Lombok 会自动生成以下代码逻辑:
equals()方法会比较所有非静态、非 transient 的字段hashCode()方法会基于同样的字段计算哈希值- 生成的代码会正确处理 null 值情况
2.2 生成的代码解析
了解 Lombok 实际生成的代码有助于我们更好地使用它。以上面的 Product 类为例,生成的 equals() 方法大致相当于:
java复制public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
return Objects.equals(id, product.id) &&
Objects.equals(name, product.name) &&
Objects.equals(price, product.price);
}
而 hashCode() 方法则类似于:
java复制public int hashCode() {
return Objects.hash(id, name, price);
}
注意:实际生成的代码会更复杂一些,包含更多的空值检查和优化,但核心逻辑是一致的。
3. 高级配置选项详解
3.1 callSuper 属性的正确使用
callSuper 属性用于控制是否在生成的代码中包含对父类字段的比较。这是一个容易出错的地方,需要特别注意。
java复制@EqualsAndHashCode(callSuper = true)
public class AdminUser extends User {
private String adminLevel;
}
这种情况下:
equals()会先调用super.equals()比较父类字段- 然后再比较子类特有的字段
hashCode()也会将父类的哈希值纳入计算
常见陷阱:
- 当父类没有重写
equals()时(即使用 Objec
