项目中自定义了一个 Java Class,名为 Student,含有属性 stuNm(姓名) 和 age(年龄)。现有一场景,将对象作为 key,成绩作为 value,存储到 Map 中,后续根据学生对象取出其成绩。只要姓名和年龄相同,就认为是同一个学生。
对于 Map 中存取值,都是依据 key 的 hashCode 值,通过计算后存到对应的桶里(Java8 之前)。上述场景,学生对象作为 Map 的 key 时,需要重写 hashCode 和 equals 方法,当 stuNm 和 age 相同时,就认为对象相等且 hashCode 值相等。
如何快速生成 equals() 和 hashCode() 方法,参见 《IDEA 快速为 Java Class 重写 equals() 和 hashCode() 方法》。Student 类及重写后的 equals() 和 hashCode() 方法如下所示。
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;
}
}
测试方法如下所示。
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("张三", "20");
map.put(stuB, "93");
System.out.println(map.get(stuA)); // 93
System.out.println(map.get(stuB)); // 93
Student stuC = new Student("张三", "20");
System.out.println(map.get(stuC)); // 93
System.out.println(stuA.equals(stuC)); // true
}
}
不同的学生对象,名字均为张三,年龄均为20,因为重写了 equals() 和 hashCode(),在进行 Map 的 put() 和 get() 操作时,被认为是同一个 key,最终的 value 值为93。