==比较地址,equals比较值?错了!!【一文搞懂== 与equals 的底层区别】 您所在的位置:网站首页 老坑砚台的区别和特点是什么样的 ==比较地址,equals比较值?错了!!【一文搞懂== 与equals 的底层区别】

==比较地址,equals比较值?错了!!【一文搞懂== 与equals 的底层区别】

2024-07-05 02:04| 来源: 网络整理| 查看: 265

最近有位小伙伴去一家互联网公司面试,结果被问:“你是如何理解==与equals的?” 他支支吾吾半天没回答到重点。结果可想而知了~~~

这道题在笔试中的出镜率相当高,下面一起来看看。

▌一、== ➊ 如果是基本数据类型的比较,则比较的是值。 int a = 1000; int b = 999; if(a == b){ System.out.println("a == b"); }

这里 == 比较的是a的值1000和b的值999是否相当。

基本数据类型:

byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。 short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。 int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。 long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。 float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。 double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。 boolean:只有true和false两个取值。 char:16位,存储Unicode码,用单引号赋值。

如果 == 用于以上八种基本数据类型比较的时候,比较的是值。

➋ 如果是包装类或者引用类的比较,则比较的是对象地址。 User user1 = new User("张三",20); User user2 = new User("老田",20); if(user1 == user2){ System.out.println("老田就是张三"); }

这时候比较的是user1指向的地址和user2指向的地址是否一致。

▌二、equals

网上都说,equals是比较的是内容,这是不对的,具体问题具体分析。

➊ 没有重写equals方法 //以下是源码 public boolean equals(Object anObject) { //同一个对象地址,直接返回true if (this == anObject) { return true; } return false; 没有重写,Object中的equals方法,比较的就是两个对象的地址(就是使用==来比较的)

举例: 自定义的对象就是object类,测试代码如下:

private Long id; private String userName; public User() { } public User(Long id, String userName) { this.id = id; this.userName = userName; } @Test public void Test() { User user1 = new User(1l, "小李"); User user2 = new User(1l, "小李"); System.out.println(user1.equals(user2)?true:false); }

测试结果

false ➋ 重写equals方法

重写了equals方法后,还得看equals方法是如何写的。

能被识别的数据类型(String/Integer等)源码中都是重写了eqauls方法的。

在Integer中 //以下是源码 public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; } 在Integer中 比较的就是对应的数字的值. 在String中 //以下是源码 public boolean equals(Object anObject) { //同一个对象地址,直接返回true if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; //字符串长度不一直,就直接返回false if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; //长度一样的字符串,然后比较字符串中的内容 while (n-- != 0) { //挨个比较,只要有不一致的就返回false if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }

举个栗子:

String aa = "abcd"; String bb = "abcde"; aa.equals(bb) 在String中 先是比较地址,地址一样就返回true,地址不一样会根据不同数据类型去执行比较值的方法

Integer和String 中 == 、equals代码验证结果如下:

在这里插入图片描述

自定义类中重写equals方法 //以下是自定义类 public class User { private Long id; private String userName; public User() { } public User(Long id, String userName) { this.id = id; this.userName = userName; } //equals方法爱怎么写就怎么写 //比如说一个正常的人比较,只要身份证号一样,那就肯定是同一个人了。 //所以在equals的时候我们也可以只比较身份证号就可以了。 @Override public boolean equals(Object o) { //同一个对象地址,直接返回true if (this == o) { return true; } //为null或者Class不一致返回false if (o == null || getClass() != o.getClass()) { return false; } User user = (User) o; //当两个对象的id相同并且userName相同才返回true return Objects.equals(id, user.id) && Objects.equals(userName, user.userName); } @Override //该方法也要重写,不然无法比较对象hashcode public int hashCode() { return Objects.hash(id, userName); } }

上面的写法中Objects.equals(id, user.id) && Objects.equals(userName, user.userName)

equals比较的是对象中 id 的值和 userName 的地址

再来一种自定义的equals写法 public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }

上面的写法中 equals比较的是对象的地址

总结: 对象重写equals,根据不同的属性类型, 可以有很多种不同的比较方法 ▌三、总结

一起来回顾一下吧

==用于基本数据类型比较的是值 ==用于包装类(引用类)比较的是对象地址 equals方法没有重写还是比较对象地址 重写equals方法后要看是如何重写的(Object(地址)、Integer(值)、String(先地址后值、地址不同值相同返回true)、自定义类(可以自己定义))

下次,你知道该怎么回答了吗?

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有