问题1. new Student 对象两个.年龄和姓名都一样。问equase对象是否相等
答:不重写的话是不相等的,因为equase底层是==
public boolean equals(Object obj) {return (this == obj);}
示例:
Student student1=new Student();student1.setCode("1111");student1.setName("名字1");//2080166188System.out.println("student1的hashCode==="+student1.hashCode());Student student2=new Student();student2.setCode("1111");student2.setName("名字1");//1123225098System.out.println("student2的hashCode==="+student2.hashCode());boolean equals = student1.equals(student2);//falseSystem.out.println("student1.equals(student2)=="+equals);

重写equase后 equals的值 是true:
问题二.只重写equase 不重写hashcode可以吗?
答:不可以。重写了equase 虽然相等的两个对象equase 的值会是true. 但是如果把对象存到HashMap,HashMap的key不能重复。不重写hashcode相等的对象会认为是不相等的:
为什么?
1. equals()相等的两个对象,hashCode()一定相等
而hashCode()相等的对象,equals()不一定相等。
hash类存储结构(HashSet、HashMap等等)添加元素会先重复性校验,校验的方式就是先判断hashCode是否相等,然后再判断equals方法,不相等就不会比对equals方法了。
不重写hashCode()默认使用的就是Object类的hashCode(),我们看下源码:
public native int hashCode();
是个native方法,其实hashcode是根据对象的内存地址经哈希算法得来的。
两个对象值相同,内存地址不同,只重写equals()而不重写hashcode()就会导致equals()相等的两个对象,hashcode()不同,hashcode的高效率就会变得无意义了。
Student类:@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return Objects.equals(code, student.code) && Objects.equals(name, student.name);}/* @Overridepublic int hashCode() {return Objects.hash(code, name);}*/
测试类:
public static void main(String[] args) {Student student1=new Student();student1.setCode("1111");student1.setName("名字1");System.out.println("student1的hashCode==="+student1.hashCode());Student student2=new Student();student2.setCode("1111");student2.setName("名字1");System.out.println("student2的hashCode==="+student2.hashCode());boolean equals = student1.equals(student2);System.out.println("student1.equals(student2)=="+equals);Student student3=new Student();student3.setCode("333");student3.setName("名字3");System.out.println("student3的hashCode==="+student3.hashCode());Map<Student,String> map= new HashMap<>();map.put(student1,"student1");map.put(student2,"student2");map.put(student3,"student3");System.out.println(map.toString());}
输出的值:
student1的hashCode===2080166188student2的hashCode===1123225098student1.equals(student2)==truestudent3的hashCode===606548741{Student{code='1111', name='名字1'}=student1,Student{code='333', name='名字3'}=student3,Student{code='1111', name='名字1'}=student2}
重写equals和hashcode后输出的值:
student1的hashCode===68164616student2的hashCode===68164616student1.equals(student2)==truestudent3的hashCode===22973655{Student{code='1111', name='名字1'}=student2,Student{code='333', name='名字3'}=student3}
问题三.什么时候重写equals
答:想要比较两个对象里的所有字段都相等就要重写equals和hashcode. 因为默认是比较引用地址相当于==
注意:
如果 实体类里加 Lombok的@Data注解 就默认是重写了equals和hashcode
因为@Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。
但是@Data默认不会调用父类的equals和hashCode方法,当本类的值相等就返回true,父类的值不会对比,如果需求是父类也要对比,那在子类上加注解@EqualsAndHashCode(callSuper = true),并重写父类的equals和hashCode方法即可
