equals和hashcode踩坑记录
准备环境
测试实体类
生成get/set , toString,无参数构造器,全参数构造器,并生成hashcode和equals方法
import lombok.Data;
@Data //lombok注解
@AllArgsConstructo //生成全参数构造器,生成全参数构造器,就要生成无参数构造器
@NoArgsConstructor//生成无参构造器
public class Student {
private Integer id;
private String naem;
private Integer age;
private Double score;
}
测试的辅组类
import java.util.ArrayList;
import java.util.List;
public class StudentData {
public static List<Student> getStudents(){
List<Student> list=new ArrayList<Student>();
list.add(new Student(1,"刘备",18,90.4));
list.add(new Student(2,"张飞",19,87.4));
list.add(new Student(3,"关羽",21,67.4));
list.add(new Student(4,"赵云",15,89.4));
list.add(new Student(5,"马超",16,91.4));
list.add(new Student(6,"曹操",19,83.4));
list.add(new Student(7,"荀彧",24,78.4));
list.add(new Student(8,"孙权",26,79.4));
/**设置两个相同的数据*/
list.add(new Student(9,"鲁肃",21,93.4));
list.add(new Student(9,"鲁肃",21,93.4));
return list;
}
}
使用stream流进行去重
@Test
public void testStreamDistinct(){
List<Student> list = StudentData.getStudents();
list.stream().distinct().forEach(System.out::println);
}
/*控制台打印*/
Student(id=1, naem=刘备, age=18, score=90.4)
Student(id=2, naem=张飞, age=19, score=87.4)
Student(id=3, naem=关羽, age=21, score=67.4)
Student(id=4, naem=赵云, age=15, score=89.4)
Student(id=5, naem=马超, age=16, score=91.4)
Student(id=6, naem=曹操, age=19, score=83.4)
Student(id=7, naem=荀彧, age=24, score=78.4)
Student(id=8, naem=孙权, age=26, score=79.4)
Student(id=9, naem=鲁肃, age=21, score=93.4)
修改实体类
生成get/set , toString,无参数构造器,全参数构造器,并生成hashcode和equals方法
public class Student {
private Integer id;
private String naem;
private Integer age;
private Double score;
public Student() {
}
public Student(Integer id, String naem, Integer age, Double score) {
this.id = id;
this.naem = naem;
this.age = age;
this.score = score;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNaem() {
return naem;
}
public void setNaem(String naem) {
this.naem = naem;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", naem='" + naem + '\'' +
", age=" + age +
", score=" + score +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Student)) {
return false;
}
Student student = (Student) o;
if (id != null ? !id.equals(student.id) : student.id != null) {
return false;
}
if (naem != null ? !naem.equals(student.naem) : student.naem != null) {
return false;
}
if (age != null ? !age.equals(student.age) : student.age != null) {
return false;
}
return score != null ? score.equals(student.score) : student.score == null;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (naem != null ? naem.hashCode() : 0);
result = 31 * result + (age != null ? age.hashCode() : 0);
result = 31 * result + (score != null ? score.hashCode() : 0);
return result;
}
}
继续单元测试
/*控制台打印*/
Student(id=1, naem=刘备, age=18, score=90.4)
Student(id=2, naem=张飞, age=19, score=87.4)
Student(id=3, naem=关羽, age=21, score=67.4)
Student(id=4, naem=赵云, age=15, score=89.4)
Student(id=5, naem=马超, age=16, score=91.4)
Student(id=6, naem=曹操, age=19, score=83.4)
Student(id=7, naem=荀彧, age=24, score=78.4)
Student(id=8, naem=孙权, age=26, score=79.4)
Student(id=9, naem=鲁肃, age=21, score=93.4)
继续修改实体类
生成get/set , toString,无参数构造器,全参数构造器
public class Student {
private Integer id;
private String naem;
private Integer age;
private Double score;
public Student() {
}
public Student(Integer id, String naem, Integer age, Double score) {
this.id = id;
this.naem = naem;
this.age = age;
this.score = score;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNaem() {
return naem;
}
public void setNaem(String naem) {
this.naem = naem;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", naem='" + naem + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
继续单元测试
/*控制台打印*/
Student{id=1, naem='刘备', age=18, score=90.4}
Student{id=2, naem='张飞', age=19, score=87.4}
Student{id=3, naem='关羽', age=21, score=67.4}
Student{id=4, naem='赵云', age=15, score=89.4}
Student{id=5, naem='马超', age=16, score=91.4}
Student{id=6, naem='曹操', age=19, score=83.4}
Student{id=7, naem='荀彧', age=24, score=78.4}
Student{id=8, naem='孙权', age=26, score=79.4}
# Student{id=9, naem='鲁肃', age=21, score=93.4}
# Student{id=9, naem='鲁肃', age=21, score=93.4}
出现了两个重复数据
结论
-
Stream流的distinct去重方法必须要实体类实现hashcode和equals方法
-
@Data注解会生成get/set,toString,equals,hashcode方法,
注意@Data是会生成hashcode和equals方法的
-
以后api设计到hashcode和equals方法要注意,如果项目中没有Lombok而是手动实现get/set…等方法,千万注意不要忘记实现hashcode和equals方法