一篇文章让你彻底学会重写equals方法

书欣 Java教程 发布时间:2022-10-01 15:59:27 阅读数:10562 1
下文笔者讲述Java中重写equals方法的相关简介及说明,如下所示

equals方法简介

在java的顶级基类中有一个对象Object类拥有一个方法equals
equals方法的功能:
    用于比较两个对象是否完全相等,当两个对象完全相等时,则返回true

Object类中equals方法的源码

java中,Object类中有一个equals方法:

public boolean equals(Object obj) {
    return (this == obj);
}
从以上代码中,我们可以看出Object中的equals方法
对比的为两个对象的引用地址
注意事项:
    在一些自定义对象中,我们通常会重写equals方法
	并采用自身定义的对象是否相同的界定规则

重写equals方法注意事项

覆盖equals方法须遵循
    自反性(reflexive)
    对称性(symmetric)
	传递性(transitive)
	一致性(consistent)
	非null对象与null进行equals比较必为false等约定。

自反性:a!=null,则a.equals(a)返回true.
对称性:a!=null,b!=null,则a.equals(b) == b.equals(a).
传递性:a!=null,b!=null,c!=null,如果a.equals(b) == b.equals(c),这a.equals(c).
一致性:a!=null,b!=null,如果a,b没有被修改,那么不管调用多少次equals,返回的结果始终只有一个.
非null对象与null进行equals比较必为false.

重写equals方法的步骤

使用“==”操作符检查参数是否是这个对象的引用。
检查参数是否为空。
检查参数类型是否匹配。
把参数转换为正确的类型。
对于类中需要进行逻辑判断的属性,检查参数的属性是否与这个对象的属性相同(比较属性也使用对于属性所属类型的equals方法)。
编写完成后,验证是否满足对称、传递、一致等特性。
写equals方法需要注意的地方
覆盖equals时总要覆盖hashCode方法,避免一些预想不到的错误。
不要将equals声明中的Object对象替换为其他类型,因为参数不同的相同方法名是重载而不是重写,这可能让程序运行结果变得难以预料。
例:
重写一个User对象中的equals方法
当用户名和手机号都相同时候,则认为两个对象是同一个用户
此时我们需重写equals和hashCode
并遵循自反、对称、传递、一致、null比较等测试
package com.java265;

public class User {
    /** 用户名 */
    private String name;
    /** 手机号 */
    private String phone;
    public User(String name, String phone) {
        super();
        this.name = name;
        this.phone = phone;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((phone == null) ? 0 : phone.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        //1.使用“==”操作符检查参数是否是这个对象的引用
        if (this == obj){
            return true;
        }
        //2.检查参数是否为空
        if (obj == null){
            return false;
        }
        //3.检查参数类型是否匹配
        if (getClass() != obj.getClass())
            return false;
        //4.把参数转换为正确的类型
        User other = (User) obj;
        //5.对于类中需要进行逻辑判断的属性,检查参数的属性是否与这个对象的属性相同
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (phone == null) {
            if (other.phone != null)
                return false;
        } else if (!phone.equals(other.phone))
            return false;
        return true;
    }
    public static void main(String[] args) {
        System.out.println("test begin");
        User a = new User("a", "139xxxxxxxx");
        User b = new User("a", "139xxxxxxxx");
        User c = new User("a", "139xxxxxxxx");
        //自反性
        assert a.equals(a);
        //传递性
        assert a.equals(b) == b.equals(c) ? a.equals(c) : false;
        //对称性
        boolean result = a.equals(b);
        assert result == b.equals(a);
        //一致性 
        for(int i = 0; i < 66; i++){
            assert result == a.equals(b);
        }
        //非null对象与null进行equals比较必为false
        assert a.equals(null) == false;
        System.out.println("test end");
        assert false;
    }
}

注意事项:
    代码启动时,需在JVM中加上 -ea选项 开启断言 
相关阅读:
Java中assert(断言)的使用
断言简介说明
什么是断言(Assert)呢?
assert断言的使用场景,有哪些呢?
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaCourse/202210/4549.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者