Lombok注解@EqualsAndHashCode
在Java开发中,我们经常需要重写equals()
和hashCode()
方法,以确保对象在集合类(如HashSet
、HashMap
等)中能正确地进行比较和存储。Lombok提供了@EqualsAndHashCode
注解,可以帮助我们自动生成这些方法,大大简化了代码编写。本文将结合具体的Java代码示例,详细介绍@EqualsAndHashCode
注解的使用。
示例代码结构
我们有三个Java文件,分别是EqualsAndHashCode使用.java
、Child.java
和Parent.java
。下面我们来详细分析这些文件。
Parent.java
package com.gqy.question.知识点.EqualsAndHashCode使用;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
class Parent{
private Integer id;
private String name;
}
这个类使用了Lombok的@Data
、@AllArgsConstructor
和@NoArgsConstructor
注解,分别用于自动生成getter、setter、toString等方法,全参数构造函数和无参数构造函数。
Child.java
package com.gqy.question.知识点.EqualsAndHashCode使用;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class Child extends Parent{
private Integer age;
private String desc;
}
Child
类继承自Parent
类,除了使用@Data
、@AllArgsConstructor
和@NoArgsConstructor
注解外,还使用了@EqualsAndHashCode(callSuper = true)
和@ToString(callSuper = true)
注解。@EqualsAndHashCode(callSuper = true)
表示在生成equals()
和hashCode()
方法时,会考虑父类的属性。
EqualsAndHashCode使用.java
package com.gqy.question.知识点.EqualsAndHashCode使用;
import java.util.HashMap;
import java.util.HashSet;
/**
* @author 顾无言
* @version 1.0
* @description: TODO
* @date 2025/2/14 9:26
*/
public class EqualsAndHashCode使用 {
public static void main(String[] args) {
Child child1 = new Child();
child1.setId(1);
child1.setName("张三");
child1.setAge(18);
child1.setDesc("美女");
Child child2 = new Child();
child2.setId(2);
child2.setName("李四");
child2.setAge(18);
child2.setDesc("美女");
/**
*不使用@EqualsAndHashCode注解,打印结果为true
* 得出结论:不使用@EqualsAndHashCode注解,默认情况下,判断的是当前类内部所有属性的值是否相等,如果相等,则认为这两个对象是相等的。
* 不会比较继承的父类属性字段
**/
/**
* 使用@EqualsAndHashCode(callSuper = false)注解,打印结果为true
* 得出结论:使用@EqualsAndHashCode(callSuper = false),判断的是当前类内部所有属性的值是否相等,如果相等,则认为这两个对象是相等的。
* 不会比较继承的父类属性字段
**/
/**
* 使用@EqualsAndHashCode(callSuper = true)注解,打印结果为false
* 得出结论:使用@EqualsAndHashCode(callSuper = true),判断的是当前类内部所有属性的值 以及 父类的所有字段属性是否相等,如果相等,则认为这两个对象是相等的。
**/
/**
* 综上:
* 不使用@EqualsAndHashCode = @EqualsAndHashCode(callSuper = false) 只比较当前类的属性字段
* @EqualsAndHashCode(callSuper = true) 比较当前类的属性字段 以及 父类的所有字段属性
**/
System.out.println(child1.equals(child2));
int i1 = child1.hashCode();
int i2 = child2.hashCode();
System.out.println(i2);
System.out.println(i1);
HashSet<Child> set = new HashSet<>();
set.add(child1);
set.add(child2);
for (Child child : set) {
System.out.println(child.toString());
}
}
}
在这个类的main
方法中,我们创建了两个Child
对象child1
和child2
,并对它们的属性进行了赋值。然后通过不同的@EqualsAndHashCode
注解使用情况进行比较,得出了以下结论:
不同使用情况及结论
不使用@EqualsAndHashCode注解
默认情况下,equals()
方法判断的是当前类内部所有属性的值是否相等,如果相等,则认为这两个对象是相等的,不会比较继承的父类属性字段。
不会重写equals()
和hashCode()
方法
使用@EqualsAndHashCode(callSuper = false)注解
这种情况下,equals()
方法判断的也是当前类内部所有属性的值是否相等,如果相等,则认为这两个对象是相等的,同样不会比较继承的父类属性字段。
重写equals()
和hashCode()
方法
使用@EqualsAndHashCode(callSuper = true)注解
此时,equals()
方法判断的是当前类内部所有属性的值以及父类的所有字段属性是否相等,只有当这些属性都相等时,才认为这两个对象是相等的。
重写equals()
和hashCode()
方法
总结
- 不使用
@EqualsAndHashCode
注解等同于@EqualsAndHashCode(callSuper = false)
,只比较当前类的属性字段。(在不考虑是否重写equals()
和hashCode()
方法) - 使用
@EqualsAndHashCode(callSuper = true)
会比较当前类的属性字段以及父类的所有字段属性。
通过合理使用@EqualsAndHashCode
注解,我们可以根据实际需求来确定对象比较时是否要考虑父类的属性,从而避免手动编写繁琐的equals()
和hashCode()
方法,提高开发效率。