由于HashMap的put方法,会先计算hashcode方法,然后根据hashcode计算桶数组的下标,然后还会有equals比较key是不是一样的,所以使用类对象作为Key需要注意hashcode方法,具体看业务诉求,看怎样判断两个对象是equals的,然后参照equals的规则,重写hashcode方法。下面一个Demo可以更好的理解这一点。
注意这里Objects.hash(id, name)方法,是Java工具类里面提供的根据多个字段快捷计算hashcode的方法。
package org.example;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class TestHashMapKey {
public static class Student {
private final int id; // 学号,假设是唯一的
private final String name; // 姓名
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return id == student.id && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + ''' +
'}';
}
}
public static void main(String[] args) {
Map<Student, Integer> scoreMap = new HashMap<>();
// 添加学生及其分数
scoreMap.put(new Student(1, "张三"), 95);
scoreMap.put(new Student(2, "李四"), 88);
scoreMap.put(new Student(3, "王五"), 92);
// 获取学生的分数
System.out.println("张三的分数: " + scoreMap.get(new Student(1, "张三"))); // 输出 95
System.out.println("李四的分数: " + scoreMap.get(new Student(2, "李四"))); // 输出 88
System.out.println("王五的分数: " + scoreMap.get(new Student(3, "王五"))); // 输出 92
scoreMap.put(new Student(3, "王五"), 95);
System.out.println("王五的分数: " + scoreMap.get(new Student(3, "王五"))); // 输出 95
// 尝试获取不存在的学生的分数
System.out.println("赵六的分数: " + scoreMap.get(new Student(4, "赵六"))); // 输出 null
}
}