• 【 java 面向对象之 Object 类】equals() 的使用和重写 equals() 方法


    📋 个人简介

    前言

    提到这个 Object 类 中的 equals() 方法,很多人对其都有一个错误的认知,并且这个==和equals() 方法的区别一直是面试中的高频考点,今天阿牛就带你看看并且重写equals方法

    回顾 == 的使用

    对于 == 运算符的使用,我不再写案例,相比大家对他都是很清楚的!

    • 可以使用在基本数据类型变量和引用数据类型变量中。
    • 如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。
    • 如果比较的是引用数据类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体 。

    equals() 方法的使用

    == 运算符对于引用数据类型变量,比的是地址值,但是我们就想比较两个引用类型内容是否相同该怎么办呢!这时equals()方法就起作用了!
    我们看下面例子:

    package 重写equals;
    
    public class Demo {
        public static void main(String[] args) {
            String str1 = new String("aniu");
            String str2 = new String("aniu");
            String str3 = "tom";
            String str4 = "tom";
            System.out.println(str3==str4);// true,str3和str4字符串在常量池中,不是new的对象,所以可以用==直接比较
            System.out.println(str1==str2);//false,str1和str2是引用类型,==比的是地址,所以要用equals比较
            System.out.println(str1.equals(str2)); //true
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    看了这个例子会给你一个错觉,认为equals()比较的是引用类型的值!

    那么你再看这个例子:

    package 重写equals;
    
    public class Demo {
        public static void main(String[] args) {
            Person p1 = new Person("aniu",21);
            Person p2 = new Person("aniu",21);
            System.out.println(p1.equals(p2)); //false
        }
    }
    
    class Person{
    
        String name;
        int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public void work(){
            System.out.println("走哇!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述
    不是说equals()比的是内容吗,p1和p2对象的属性值一样,为什么会输出false呢?
    要解决这个问题,我们要看equals()的源码:
    将鼠标放到上述代码的equals()方法上,ctrl+b查看源码

     public boolean equals(Object obj) {
            return (this == obj);
        }
    
    • 1
    • 2
    • 3

    我们可以看到equals()内部也是==运算符,对于引用类型,这不比较的也是地址嘛!当然会输出false,那第一个例子的String类型中的equals()又是怎么回事,咋就输出true呢!我们同样看String中的equals()源码:

    public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            return (anObject instanceof String aString)
                    && (!COMPACT_STRINGS || this.coder == aString.coder)
                    && StringLatin1.equals(value, aString.value);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    public static boolean equals(byte[] value, byte[] other) {
            if (value.length == other.length) {
                for (int i = 0; i < value.length; i++) {
                    if (value[i] != other[i]) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    很明显,String类将Object类中的equals()方法重写了!
    因此!我们要比较两个类是否相同,也需要重写Object类中的equals()方法!

    总结:
    equals ()方法的使用:

    1. 是一个方法,而非运算符。
    2. 只能适用于引用数据类型 。
    3. Object 类中 equals ()的定义:

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

    1. 说明: Object 类中定义的 equals ()和 == 的作用是相同的,比较两个对象的地址值是否相同。

    2. 像 String 、 Date 、 File 、包装类等都重写了 Object 类中的 equals ()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。

    3. 通常情况下,我们自定义的类如果使用 equals ()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对 Object 类中的 equals ()进行重写!

    重写自定义类中的 equals() 方法

    手动重写

    我们参考String类中重写的equals()方法以及我们自己的理解,手动重写一下自定义类中的equals()方法。

    重写的原则,比较两个对象的实体内容是否相同!

    package 重写equals;
    
    public class Demo {
        public static void main(String[] args) {
            Person p1 = new Person("aniu",21);
            Person p2 = new Person("aniu",21);
            System.out.println(p1.equals(p2));
        }
    }
    
    class Person{
    
        String name;
        int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public void work(){
            System.out.println("走哇!");
        }
        
        //手动重写equals()方法
        @Override
        public boolean equals(Object obj) {  // 参数将其进行了上转型,使其可以接受任何对象
            //如果两个对象的地址值相同
            if (this == obj){
                return true;
            }
            if (obj instanceof Person){
                Person p = (Person) obj; //下转型
                return this.age == p.age && this.name == p.name; // 比较两个对象的属性值是否相同
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这里插入图片描述
    可以看到此时为true了!

    自动重写

    在开发中我们往往用idea帮助我们自动重写equals()方法,并且自动重写的equals()方法也更加规范,接下来看看操作步骤吧!
    首先,在idea中用快捷键Alt+Insert:
    在这里插入图片描述
    点击之后
    在这里插入图片描述
    设置如上图这样后点击Next

    在这里插入图片描述
    将两个属性全部勾选后继续Next
    在这里插入图片描述
    hashCode()方法也一样!Next
    在这里插入图片描述
    不勾选,Finish,然后我们的equals()方法就自动重写好了!

    package 重写equals;
    
    public class Demo {
        public static void main(String[] args) {
            Person p1 = new Person("aniu",21);
            Person p2 = new Person("aniu",21);
            System.out.println(p1.equals(p2));
        }
    }
    
    class Person{
    
        String name;
        int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public void work(){
            System.out.println("走哇!");
        }
    
        // 自动重写equals()
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Person)) return false;
    
            Person person = (Person) o;
    
            if (age != person.age) return false; 
            return name != null ? name.equals(person.name) : person.name == null;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述
    运行是true,没有问题!
    注意 name.equals() 调的是String里面重写的equals()方法!

    面试题:== 和 equals 的区别

    相信通过上面的内容,现在你可以正确的说出 == 和 equals 的区别了

    1. == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址。
    2. equals 的话,它是属于 java.lang.Object 类里面的方法,如果该方法没有被重写过默认也是==;我们可以看到 String 等类的 equals 方法是被重写过的,而且 String 类在日常开发中用的比较多,久而久之,形成了 equals 是比较值的错误观点。
    3. 具体要看自定义类里有没有重写 Object 的 equals 方法来判断。
    4. 通常情况下,重写 equals 方法,会比较类中的相应属性是否都相等。

    重写 equals () 方法的原则

    • 对称性:如果 x.equals (y)返回是“ true ”,那么 y.equals (x)也应该返回是“ true ”。
    • 自反性: x.equals (x)必须返回是“ true ”。
    • 传递性:如果 x.equals (y)返回是“ true ”,而且 y.equals (z)返回是“ true ”,那么 z.equals (x)也应该返回是“ true ”。
    • 一致性:如果 x.equals(y) 返回是“ true ”,只要x和 y 内容一直不变,不管你重复 x.equals (y)多少次,返回都是“ true ”。
    • 任何情况下, x.equals (null),永远返回是“ false ”;x.equals (和 x 不同类型的对象) 永远返回是“ false ”。

    结语

    如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

    🏰系列专栏
    👉软磨 css
    👉硬泡 javascript
    👉flask框架快速入门

  • 相关阅读:
    waf绕过
    【计算机毕业设计】45.医院挂号系统
    Promise.all如果其中之一失败,怎么能够拿到其他成功的结果
    MyBatis笔记
    “Notepad++“ 官网地址
    436. 寻找右区间--LeetCode_二分
    校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)
    求最大公约数
    Java中的锁
    OpenCV读取ESP32CAM的视频流
  • 原文地址:https://blog.csdn.net/qq_57421630/article/details/126557343