题目:
(场景提)现在有一个学生表,字段为学校、班级、姓名、语文成绩,我需要进行去重,依据为学校、班级、姓名一样就认为是同一个学生,现在丢到set里面进行去重,要怎么样实现一个去重效果?
思路:
Set集合本身就无法存储重复元素,所以我们唯一需要考虑的仅仅是将对象存入Set集合时,如何让Set集合按我们需要的规则将符合条件的对象认为是相同的对象。
原理:
Set集合判断元素是否相同的流程:
1. 哈希值比较
- 首先调用元素的
hashCode()
方法计算哈希值 - 比较两个元素的哈希值是否相等
- 如果哈希值不相等,直接判定为不同元素
- 如果哈希值相等,进入下一步判断
2. 引用或值比较
- 检查两个元素是否是同一个对象(引用相等)
- 如果是同一个对象,判定为相同元素
- 如果不是同一个对象,继续下一步
- 调用
equals()
方法进行精确比较- 如果
equals()
返回true
,判定为相同元素 - 如果
equals()
返回false
,判定为不同元素
- 如果
做法:
那么很容易就可以想到,我们只需要按照数据库字段创建一个与之对应的实体类,重写hashCode()与equals()后,直接将对象存入Set集合中即可自动去重。
代码:
public class Student {
private String school;
private String className;
private String name;
private double score;
public Student(String school, String className, String name, double score) {
this.school = school;
this.className = className;
this.name = name;
this.score = score;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
if (school != null ? !school.equals(student.school) : student.school != null) return false;
if (className != null ? !className.equals(student.className) : student.className != null) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = school != null ? school.hashCode() : 0;
result = 31 * result + (className != null ? className.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
class App {
public static void main(String[] args) {
Student stu_1 = new Student("xxx", "1班", "小明", 99.00);
Student stu_2 = new Student("xxx", "1班", "小明", 99.00);
System.out.println(stu_1.hashCode());
System.out.println(stu_2.hashCode());
System.out.println(stu_1.equals(stu_2)); // true
}
}