Java 自定义对象作为 Map 的 key 时,需重写 equals() 和 hashCode() 方法。
IDEA 可以快速为 Java Class 重写 equals() 和 hashCode() 方法。
Lombok 的 @Data 注解可以为 Java 类自动生成 equals() 和 hashCode() 方法,使用 @Data 注解会自动添加以下注解:
- @Getter
- @Setter
- @RequiredArgsConstructor
- @ToString
- @EqualsAndHashCode
@Data 相当于 @Getter、@Setter、@RequiredArgsConstructor、@ToString、@EqualsAndHashCode 这 5 个注解的合集。其中,@EqualsAndHashCode 注解的作用,即为 Java 类重写了 equals() 和 hashCode() 方法,详情见 @EqualsAndHashCode 官网说明 。
官网文档中提到的大致有以下几点:
- 此注解会生成 equals(Object other) 和 hashCode() 方法。
- 它默认使用非静态,非瞬态的属性。
- 可通过参数 Exclude 排除一些属性。
- 可通过参数 Include 指定使用哪些属性。
- 它默认仅使用该类中定义的属性且不调用父类的方法。
- 可通过 @EqualsAndHashCode(callSuper=true) 解决上一点问题。让其生成的方法中调用父类的方法。
测试类及测试方法如下所示。
package com.test.model;
import lombok.Data;
@Data
public class Student {
// 姓名
private String stuNm;
// 年龄
private String age;
// 构造函数
public Student(String stuNm, String age) {
this.stuNm = stuNm;
this.age = age;
}
}
package com.test.model;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<Student, String> map = new HashMap<>();
Student stuA = new Student("张三", "20");
map.put(stuA, "95");
Student stuB = new Student("张三", "21");
map.put(stuB, "93");
System.out.println(map.get(stuA)); // 95
System.out.println(map.get(stuB)); // 93
Student stuC = new Student("张三", "20");
System.out.println(map.get(stuC)); // 95
System.out.println(stuA.equals(stuC)); // true
System.out.println(stuA.hashCode() == stuC.hashCode()); // true
}
}
因为 stuA 和 stuC 的姓名和年龄都相同,所以按照重写后的 equals() 和 hashCode() 得出,stuA.equals(stuC) 且 stuA 和 stuC 的 hashCode 值相等。