栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

equals和==的区别

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

equals和==的区别

问题1. new Student 对象两个.年龄和姓名都一样。问equase对象是否相等
答:不重写的话是不相等的,因为equase底层是==

public boolean equals(Object obj) {
        return (this == obj);
    }

示例:

Student student1=new Student();
student1.setCode("1111");
student1.setName("名字1");
//2080166188
System.out.println("student1的hashCode==="+student1.hashCode());

Student student2=new Student();
student2.setCode("1111");
student2.setName("名字1");
//1123225098
System.out.println("student2的hashCode==="+student2.hashCode());

boolean equals = student1.equals(student2);
//false
System.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类:
 @Override
 public 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);
 }

  

测试类:

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 map= new HashMap<>();
  map.put(student1,"student1");
  map.put(student2,"student2");
  map.put(student3,"student3");
  System.out.println(map.toString());
}

输出的值:

student1的hashCode===2080166188
student2的hashCode===1123225098
student1.equals(student2)==true
student3的hashCode===606548741
{Student{code='1111', name='名字1'}=student1, 
Student{code='333', name='名字3'}=student3, 
Student{code='1111', name='名字1'}=student2}

重写equals和hashcode后输出的值:

student1的hashCode===68164616
student2的hashCode===68164616
student1.equals(student2)==true
student3的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方法即可

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/880967.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号