重写Object.equals()总结

equals()规范,假设对象都不为null:

  1. 自反性:x.equals(x)=true
  2. 对称性:x.equals(y)=y.equals(x)
  3. 传递性:x.equals(y) and y.equals(z) = x.equals(z)
  4. 一致性:当x与y对象内容未改变时,x.equals(y)的值永远不变
  5. 非空性:x.equals(null)=false

 

重写equals()分为5步:

  1. this==obj判断若是同一引用则肯定相等直接返回true
  2. obj==null判断obj为null直接返回false(因为能调用equals就表明this不为null,两者不相等)
  3. getClass或者instanceof判断是否属于同一类(涉及继承需分情况选择)
  4. 将obj强制转换为当前类
  5. 对比各个域的值是否相等(若成员是对象则应该使用Objects.equals(Field1,Field2)来判断是否相等,避免其中有一个是null造成的异常)
    @Override
    public boolean equals(Object o) {
        // 1.判断是否同一引用
        if (this == o) return true;
        // 2.如果传入的对象为null返回false
        if (o == null)return false;
        // 3.判断是否同一类
        if (!(o instanceof User)) return false;
        // 4.转换为当前类
        User user = (User) o;
        // 5.比较各个字段
        return getAge() == user.getAge() &&
                Objects.equals(getName(), user.getName());
    }

举例:Manager类(int bonus;String sex),Person类(String name)

getClass与instanceof对比:getClass判断精确某一类,instanceof可以是父类或接口

getClass:精确判断对象的类型

instanceof:判断是否是某类型,可以是父类或者接口

Manager instanceof Person ->true(Manager也是Person)

Person instanceof Manger->false(不是每个Person都是Manager)

1.没有继承Person类,直接继承Object类

个人定义equals的意义,任意选择getClass或instanceof来实现第三步:对比是否属于同一类

    @Override
    public boolean equals(Object obj) {
        //1.如果引用相同的对象直接返回true
        if(this==obj)return true;
        //2.因为能够调用equals则表明this不为null,所以如果obj为null,直接返回false
        if(obj==null)return false;
        //3.判断是否同一类
        if(getClass()!=obj.getClass())return false;
        if(!(obj instanceof Manager))return false;
        //4.将obj强制类型转换为当前类型
        Manager object=(Manager)obj;
        //5.调用父类对象的equals与子类特有域一一对比,因为对象域如String要使用equals必须确保不为null所以要采用Objects.equals(field1,field2)来对比
        return Objects.equals(this.sex,object.sex)
                &&this.bonus==object.bonus;
    }

2.继承Person类

2.1若是子类Manager有自己的相等概念定义,则强制使用getClass来确保类型精确相等

    @Override
    public boolean equals(Object obj) {
        //1.如果引用相同的对象直接返回true
        if(this==obj)return true;
        //2.因为能够调用equals则表明this不为null,所以如果obj为null,直接返回false
        if(obj==null)return false;
        //3.判断类型相等
        if(getClass()!=obj.getClass())return false;//4.将obj强制类型转换为当前类型
        Manager object=(Manager)obj;
        //5.调用父类对象的equals并且子类特有域一一对比,因为对象域如String要使用equals必须确保域参数如this.sex不能为null所以要采用Objects.equals(field1,field2)来对比
        return super.equals(obj)
                &&Objects.equals(this.sex,object.sex)
                &&this.bonus==object.bonus;
    }

2.2若是由父类Person定义相等的概念,则应该在父类重写equals方法,将该方法设为final使得子类不能重写,然后使用instanceof进行检测,这样Person的不同子类之间都可以比较;

    @Override
    public final boolean equals(Object obj) {
        //1.如果引用相同的对象直接返回true
        if(this==obj)return true;
        //2.因为能够调用equals则表明this不为null,所以如果obj为null,直接返回false
        if(obj==null)return false;
        //3.精确要求类型相等
        if(getClass()!=obj.getClass())return false;
        //3.判断类型是否相等(同一继承链)
        if(!(obj instanceof Person))return false;
        //4.将obj强制类型转换为当前类型
        Person object=(Person) obj;
        //5.调用父类对象的equals与子类特有域一一对比,因为对象如String要使用equals必须确保域参数不为null否则抛出NullPointer错误,所以要采用Objects.equals(field1,field2)来对比
        return Objects.equals(Field,Field)
    }

数组equals()

Arrays.equals(type[] array1,type[] array2)

重写了equals()就必须重写其hashcode():

https://www.cnblogs.com/ming-szu/p/9158394.html

-----参考<Java 核心技术 卷I>P166

原文地址:https://www.cnblogs.com/ming-szu/p/9157729.html