关注“Java后端技术全栈”

回复“000”获取大量电子书

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

这道题在笔试中的出镜率相当高,其实很简单。

==

基本数据类型

如果是基本数据类型的比较,则比较的是值。

1int a = 1000;
2int b = 999;
3if(a == b){
4    System.out.println("a == b");
5}

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

基本数据类型:

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

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

包装类(引用类)

如果是包装类或者引用类的比较,则比较的是对象地址。

1User user1 = new User("张三",20);
2User user2 = new User("老田",20);
3if(user1 == user2){
4   System.out.println("老田就是张三");
5}

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

equals

没有重写equals方法

是Object的方法。

网上都说,equals是比较的是内容,很多都是瞎说。具体问题具体分析。

如果比较的类没有重写Object中的equals方法,那么比较的就是两个对象的地址,就是使用==来比较的。

重写equals方法

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

典型的String/Integer等这些都是重写了eqauls方法的。

在Integer中

1    public boolean equals(Object obj) {
2        if (obj instanceof Integer) {
3            return value == ((Integer)obj).intValue();
4        }
5        return false;
6    }

比较的就是对应的数字。

在String中

 1    public boolean equals(Object anObject) {
 2        //同一个对象地址,直接返回true
 3        if (this == anObject) {
 4            return true;
 5        }
 6        if (anObject instanceof String) {
 7            String anotherString = (String)anObject;
 8            int n = value.length;
 9            //字符串长度不一直,就直接返回false
10            if (n == anotherString.value.length) {
11                char v1[] = value;
12                char v2[] = anotherString.value;
13                int i = 0;
14                //长度一样的字符串,然后比较字符串中的内容
15                while (n-- != 0) {
16                    //挨个比较,只要有不一致的就返回false
17                    if (v1[i] != v2[i])
18                        return false;
19                    i++;
20                }
21                return true;
22            }
23        }
24        return false;
25    }

比较的是字符串内容。

1String aa = "abcd";
2String bb = "abcde";
3aa.equals(bb)

把字符串拆成char数组进行一个一个比较。

自定义类中重写equals方法

 1public class User {
 2    private Long id;
 3    private String userName;
 4
 5    public User() {
 6    }
 7
 8    public User(Long id, String userName) {
 9        this.id = id;
10        this.userName = userName;
11    }
12
13    public Long getId() {
14        return id;
15    }
16
17    public void setId(Long id) {
18        this.id = id;
19    }
20
21    public String getUserName() {
22        return userName;
23    }
24
25    public void setUserName(String userName) {
26        this.userName = userName;
27    }
28
29    //equals方法爱怎么写就怎么写
30    //比如说一个正常的人比较,只要身份证号一样,那就肯定是同一个人了。
31    //所以在equals的时候我们也可以只比较身份证号就可以了。
32    @Override
33    public boolean equals(Object o) {
34        //同一个对象地址,直接返回true
35        if (this == o) {
36            return true;
37        }
38        //为null或者Class不一致返回false
39        if (o == null || getClass() != o.getClass()) {
40            return false;
41        }
42        User user = (User) o;
43        //当两个对象的id相同并且userName相同才返回true
44        return Objects.equals(id, user.id) &&
45                Objects.equals(userName, user.userName);
46    }
47    @Override
48    public int hashCode() {
49        return Objects.hash(id, userName);
50    }
51}

上面Objects.equals

1public static boolean equals(Object a, Object b) {
2        return (a == b) || (a != null && a.equals(b));
3}

总结

== 用于基本数据类型比较的是值

==用于包装类(引用类)比较的是对象地址。

equals方法没有重写还是比较对象地址。重写equals方法后还得看是如何重写的。

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

推荐阅读:

《Spring Cloud与Docker微服务架构实战》.pdf

《Go语言实战》.pdf

《分布式Java应用基础与实践》.pdf


田维常
166 声望18 粉丝