有一些场景需要重写 Java 类的 equals 和 hashCode 方法,如 Java 对象作为 Map 的 key 时。IDEA 提供了快速实现重写上述 2 个方法的便捷操作,过程简述如下。
定义一个 Java Class,名为:Student,代码如下。
package com.test.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Student {
// 姓名
private String stuNm;
// 年龄
private String age;
// 构造函数
public Student(String stuNm, String age) {
this.stuNm = stuNm;
this.age = age;
}
}
快速生成上述 2 个方法的过程如下:在 Student.java 文件中按下 Alt + Ins,调出 Generate,选中 “equals() and hashCode()”。
在 Generate equals() and hashCode() 窗口中,选择 “IntelliJ Default” Template。
选择被包含在 equals() 方法中的属性。
选择被包含在 hashCode() 方法中的属性。
选择所有的非 null 属性。
点击 Finish 按钮,即可快速生成 equals() 和 hashCode() 方法,生成完后的 Student.java 文件如下所示。
package com.test.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Student {
// 姓名
private String stuNm;
// 年龄
private String age;
// 构造函数
public Student(String stuNm, String age) {
this.stuNm = stuNm;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
if (stuNm != null ? !stuNm.equals(student.stuNm) : student.stuNm != null) return false;
return age != null ? age.equals(student.age) : student.age == null;
}
@Override
public int hashCode() {
int result = stuNm != null ? stuNm.hashCode() : 0;
result = 31 * result + (age != null ? age.hashCode() : 0);
return result;
}
}
如果不重写 equals() 和 hashCode() 方法,对引用对象进行对比时,默认对比的是对象内存地址。而重写方法后,只要引用对象的姓名和年龄属性值相等,即认为 2 个对象相等。测试示例如下。
package com.test.model;
import com.test.model.Student;
public class Test {
public static void main(String[] args) {
Student stuA = new Student("张三", "20");
Student stuB = new Student("张三", "20");
System.out.println(stuA.equals(stuB)); // true
System.out.println(stuA == stuB); // false
System.out.println(stuA.hashCode() == stuB.hashCode()); // true
}
}