==和equals到底是怎么回事

8 篇文章 0 订阅
5 篇文章 0 订阅

摘自微信公众号:https://mp.weixin.qq.com/s?__biz=MzU1NTg0MzMwMg==&mid=2247483752&idx=1&sn=5018d012dc4423cccba18bb6785168a4&chksm=fbcf6ae1ccb8e3f7f6aa794f3d176fe3668c9ef404fff5d1c8d7555d50abcbfdd2648939ec13&token=1247180584&lang=zh_CN#rd

 

在java中比较两个对象(包括值,new出来的对象)是否相等,最常用的就是==和equals。大家比较糊涂这两个到底有什么区别,该怎么使用。

我们知道,java中的对象类型有2种,基本数据类型和引用数据类型,基本数据类型没问题,比较值就好了,因为基本数据类型的值就存放在变量中,也不存在equals方法。

当比较的对象是引用数据类型的时候,大家才会有这个问题。

==关系运算符

String str = new String("11");

首先我们知道,java的变量是申明在栈中的,对象是创建在堆中的,如果一个变量str引用一个对象,那么这个变量里面存的就是这个对象的地址值(这里不考虑对象因为GC而导致位置重排)。不同的对象,地址一定不同,只有同一个对象,地址才会相同。

比如:

String str1 = new String("11");

String str2 = new String("11");

System.out.print(str1==str2)

这时是false,因为new的对象都是在堆中的新对象。

但是

String str1 = "11";

String str2 = "11";

System.out.print(str1==str2)

这时是true,因为"11"会被java放进常量池中,被重复引用,而并没有创建新的对象。

equals()方法

很显然这是对象的方法。如果没有子类重写的话,默认调的总是Object类的equals方法,因为在java里面所有的类都继承自Object,不需要声明出来,所以所有的对象都会有equals方法。

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

这是Object中的方法返回的,默认就是使用的==关系运算符,就是比较两个对象的地址,换句话说就是看他们是不是同一个对象,并不关系对象的内容。而我们在业务中关系的是对象的内容是否相同,而不关系他们是不是同一个对象。

在默认情况下,==和equals是相同的,都是看两个对象地址是不是相同,即是不是同一个对象。

如果想比较对象的内容,就需要重写equals方法,因为==运算符我们拿他没办法。我们看看String是怎么重写equals方法的

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

他是拿到这2个字符串的字符数组,然后挨个去比较字符是不是相等,有一个字符不相等就返回false。所以字符串的equals是被重写了的equals,不再是Object的equals方法了。所以我们想比较啥,就把这个方法写成啥。

我们自己实现一下:

public class Student {

    private String a;
    private String b;
    
    public Student(String a, String b) {
        this.a = a;
        this.b = b;
    }
    
}
public static void main(String[] args) {
  Student student1 = new Student("1", "2");
  Student student2 = new Student("1", "2");
  System.out.println(student1 == student2);
    System.out.println(student1.equals(student2));
}

输出的是false,false,因为这2个不是同一个对象

我们在Student中重写equals方法

public class Student {

    private String a;
    private String b;
    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    public Student(String a, String b) {
        this.a = a;
        this.b = b;
    }

    public boolean equals(Object o) {
        Student s = (Student) o;
        return s.getA().equals(this.a) 
                && s.getB().equals(this.b);
    }

}
public static void main(String[] args) {
  Student student1 = new Student("1", "2");
  Student student2 = new Student("1", "2");
  System.out.println(student1 == student2);
  System.out.println(student1.equals(student2));
}

输出是false,true。重写了equals就会覆盖父类Object的equals方法,调的时候就会调子类的。

 

总之,==就是看是不是同一个对象,equals()就是调equals()方法,方法怎么写,就是怎么着。

 

摘自微信公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值