@EqualsAndHashCode(of = "id")Lombok 提供的一个注解,用于自动生成 equals()hashCode() 方法,并且只基于指定的字段(这里是 id)进行比较和哈希计算


✅ 一、作用详解

@EqualsAndHashCode(of = "id")
public class User {
    private Long id;
    private String name;
    private String email;
}

等价于手写以下代码:

@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); // 只比较 id
}

@Override
public int hashCode() {
    return Objects.hash(id); // 只用 id 计算哈希值
}

🔑 关键点

  • 只有 id 字段参与 equals() 比较
  • 只有 id 字段参与 hashCode() 计算
  • nameemail 等其他字段完全被忽略

✅ 二、为什么用 of = "id"

常见场景:
  1. 数据库实体类(Entity)

    • 在 ORM(如 Hibernate、MyBatis)中,主键 id 唯一标识一个对象
    • 即使其他字段不同,只要 id 相同,就认为是同一个实体
    • 避免因非主键字段变化导致 Set 或 Map 中重复插入
  2. 避免可变字段影响哈希一致性

    • 如果 hashCode() 包含可变字段(如 name),对象放入 HashSet 后修改 name,会导致无法再找到该对象(因为哈希桶变了)
    • 使用不可变的 id(通常是主键)更安全
  3. 性能优化

    • 只比较一个字段,比比较所有字段更快

✅ 三、与其他 Lombok 注解对比

注解 行为
@EqualsAndHashCode 使用所有非静态、非 transient 字段
@EqualsAndHashCode(exclude = "name") 使用所有字段,排除 name
@EqualsAndHashCode(of = "id") 仅使用 id 字段(最严格)✅
@EqualsAndHashCode(callSuper = true) 包含父类字段

💡 ofexclude 不能同时使用


✅ 四、注意事项 ⚠️

  1. 确保 id 是不可变的(immutable)

    • 一旦对象创建后,id 不应再改变
    • 否则仍会导致 HashSet/HashMap 行为异常
  2. 适用于“实体”而非“值对象”

    • 实体(Entity):由 ID 标识(如用户、订单)
    • 值对象(Value Object):由所有字段共同定义相等性(如地址、金额)
  3. 与 JPA/Hibernate 兼容性好

    Hibernate 推荐实体类的 equals()/hashCode() 基于主键实现 

✅ 五、实际应用示例

@Entity
@Table(name = "users")
@EqualsAndHashCode(of = "id") // ✅ 推荐做法
public class User {
    @Id
    private Long id;
    private String username;
    private String password;

    // 即使密码被重置,只要 id 相同,就是同一个用户
}

测试:

User u1 = new User(1L, "alice", "123");
User u2 = new User(1L, "alice", "456");

System.out.println(u1.equals(u2)); // true(因为 id 相同)
System.out.println(u1.hashCode() == u2.hashCode()); // true

✅ 总结

@EqualsAndHashCode(of = "id") 的含义是:
“两个对象是否相等,只看它们的 id 是否相等;哈希值也只由 id 决定。”

这是数据库实体类的最佳实践之一,能有效避免集合操作中的逻辑错误,同时符合 JPA/Hibernate 的设计哲学。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐