equals与==的区别、重写jdk中equals方法和应用场景,教你如何轻松记忆!

大家好,我是Ziph!

让我们来一起轻松区分==和equals的比较!

== 的概念

比较的是变量(栈)内存中存放对象(堆)的地址,用来判断两个两个对象的地址是否相同,也就是说是否指向同一个对象(听起来也许比较晦涩难懂,但是我下面用通俗易懂的说法来给大家解释!)

  • 简单来说,== 就是比较的地址是否相同
  • 用于比较创建也就是实例化的对象地址,且必须是同一类型
  • 比较的结果是true或false
  • 还可用于比较两端的变量都代指的数字,比如说:账号假如是int型的,对账号输入的校验就可以用==来比较,因为两端的值都是指向堆中的

equals的概念

equals比较的是两个对象的内容,因为Object类中的equals的默认方法是public boolean equals(Object obj){},而所有的类都隐式的继承与Object类,所以适用于所有对象。如果没有对equals方法进行重写覆盖的话,而Object中的equals方法返回的却是==的判断(也就是比较的地址)

  • 简单来说,equals比较的是内容,但是在没有覆盖Object中equals方法的同时,它比较的也是地址
  • 用于比较字符串
  • 也可以举同样的例子,比如:账号密码是String类型的话,我们就需要用equals来比较了
  • 不同字符串的比较
    • String s = “Hello”; 这种字符串定义是产生了一个对象存储在字符串池中的
    • String s = new String(“Hello”); 虽然看起来都是Hello,但是地址也发生了变化,而这中定义方式,产生了两个对象,一个存储在字符串池中,而另一个存储在堆中
    • 然后用equals比较这两种的时候那就是返回false了

注意:== 比equals的运行速度要快,因为只是比较的单纯地址

字符串的比较

/** 
* @author Ziph
* @date 2020年2月28日
* @Email [email protected]
*/
public class TestStr {
	public static void main(String[] args) {
		//特殊字符串的比较
        String str1 = "abc";
        String str2 = "abc";
        String str3 = new String("abc");
        System.out.println(str1 == str2);         //都产生一个对象且地址内容都相同,返回true
        System.out.println(str1.equals(str3));    //内容相同返回true
        System.out.println(str1 == str3);         //比较的是地址,地址不同则返回false
	}
}

那么什么时候需要重写覆盖equals方法呢?

在这里插入图片描述

首先覆盖equals方法的应用场景是根据业务需求来定的,比如:(举的栗子通俗易懂,虽然有点长,如果你不明白的话建议去读!)

 
       学生Ziph在学校的端口(学生信息管理系统)存储自己的学生数据,他存储了一遍,有怕没有存上,然后又存储了一遍。那么我们想想,会出现两个Ziph同学的信息吗?而现实中并不会,对吧。

       假如说存储了两遍,也就是创建了两个Ziph学生的信息对象,开辟了两块空间,那么我们用equals去校验的时候,只判断了两个对象地址,内容就无法判断了。熟知Java是模拟现实世界解决现实问题,那么这不符合现实啊。这位同学存了两遍,就有两个Ziph同学吗?答案很明显肯定不可能的!

       这时候我们就需要重写equals方法了,让他既能判断地址也能判断内容,这就是这个例子中的业务需求!我们以后会根据不同的业务需求去重写equals判断的方法!(而且是经常写!!!)
 
 
Object默认equals方法

//Object类中的默认实现方式
class Object {
    public boolean equals(Object obj) {
        return (this == obj);
    }
}

重写equals方法代码

/**
 * @Author Ziph
 * @date 2020/2/28
 * @Email [email protected]
 */
public class TestStudent {
    public static void main(String[] args) {
        //s1和s2地址不同而内容相同
        Student s1 = new Student("Ziph", 21, "131000042424249090", 100);
        Student s2 = new Student("Ziph", 21, "131000042424249090", 100);
        //s1和s3地址不同内容也不同
        Student s3 = new Student("Tom", 21, "131000042424249090", 99);

        //开始比较
        System.out.println(s1.equals(s2));      //true
        System.out.println(s1.equals(s3));      //false
    }
}

class Student {
    private String name;			//姓名
    private int age;				//年龄
    private String id;				//身份证号码
    private double score;			//分数

    public Student(String name, int age, String id, double score) {
        this.name = name;
        this.age = age;
        this.id = id;
        this.score = score;
    }

    public boolean equals(Object obj) {
        //1.比较两个对象的地址是否一样
        if (this == obj) {
            return true;
        }

        //2.判断对象不能为空,做的非空判断
        if (obj == null) {
            return false;
        }

        //3.确认类型,确认是同一类型,在这个案例中确认是学生对象类型
        if (this.getClass() != obj.getClass()) {
            return false;
        }

        //4.转型(转型的前提是类型肯定是Student,也就是说必须是同一类型,在上面已经做过了判断)
        //转型的目的就是把obj类型强转为学生类,即:Student类型
        Student stu = (Student)obj;

        //5.比较内容,假如是内容相同那么我们就认为他们是同一个人
        //也就是覆盖后的equals
        if (this.name.equals(stu.name) && this.age == stu.age && this.id.equals(stu.id) && this.score == stu.score) {
            return true;
        }
        return false;
    }
}
发布了73 篇原创文章 · 获赞 128 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44170221/article/details/104562716