当前位置 : 主页 > 编程语言 > java >

《Java 核心技术 卷1》 笔记 第五章 继承(4)equals方法

来源:互联网 收集:自由互联 发布时间:2022-07-13
5.2.1 equals 方法 形式: public void equals ( Object object ){} 注意点: 参数类型不能修改,如果不写Object 那就是方法重载,不是方法重写; 当前类不进行方法重写,且非Object 的其他父类不进行


5.2.1 equals 方法

形式:

public void equals(Object object){}

注意点:

  • 参数类型不能修改,如果不写Object 那就是方法重载,不是方法重写;
  • 当前类不进行方法重写,且非Object 的其他父类不进行方法重写时,比较的是两个对象的地址,及两个变量是否指向同一个对象;
  • 进行方法重写时(未使用extends继承已覆盖equals的父类),通常需要几个步骤:
  • 判断是否为空,为空的情况下必然不相等(否则调用前空指针)
  • 判断是否是同一个对象,是同一个对象必然相等
  • 使用intanceof判断能否进行类型账号,不能转换必然不相等
  • 进行类型转换后比较相应的值
  • equals比较的规则,来自《Thinking in Java》
  • 自反性:自己和自己比较必然返回true;反例:
  • public class Main {

    public static void main(String[] args){

    Main solution = new Main();

    A a = solution.new A();

    System.out.println(a.equals(a));

    }



    class A{

    @Override

    public boolean equals(Object obj) {

    return false;

    }

    }

    }

            2. 对称性:如果(assume) a.equals(b)的结果为true,那么反之亦然(vice versa),b.equals(b)的结果也应为true;(补充:父子类间instanceof具有单向性,比较时需要慎重)反例:

    public class Main {
    public static void main(String[] args){
    Main solution = new Main();
    A a = solution.new A(1);
    A b = solution.new A(2);
    System.out.println(a.equals(b));
    System.out.println(b.equals(a));
    }

    class A{
    int a;
    public A(int a){
    this.a = a;
    }

    @Override
    public boolean equals(Object obj) {
    if(obj==null)
    return false;
    if(!(obj instanceof A))
    return false;
    A tmp = (A)obj;
    return this.a>tmp.a;
    }
    }
    }

            3. 传递性:如果(assume) a.equals(b)的结果为true 且b.equals(c)的结果为true,那么a.equals(c)的结果也应为true;反例:

    public class Main {
    public static void main(String[] args){
    Main solution = new Main();
    A a = solution.new A(1,3);
    A b = solution.new A(1,2);
    A c = solution.new A(3,2);
    System.out.println(a.equals(b));
    System.out.println(b.equals(c));
    System.out.println(a.equals(c));
    }

    class A{
    int a;
    int b;
    public A(int a,int b){
    this.a = a;
    this.b = b;
    }

    @Override
    public boolean equals(Object obj) {
    if(obj==null)
    return false;
    if(!(obj instanceof A))
    return false;
    A tmp = (A)obj;
    return this.a == tmp.a || this.b == tmp.b;
    }
    }
    }

            4. 一致性:如果(assume) a.equals(b)的结果为true,那么不修改a和b的情况下无论调用多少次结果都应该一样;反例:

    public class Main {
    public static void main(String[] args){
    Main solution = new Main();
    A a = solution.new A();
    A b = solution.new A();
    System.out.println(a.equals(b));
    System.out.println(a.equals(b));
    System.out.println(a.equals(b));
    }

    class A{
    Random r = new Random();

    @Override
    public boolean equals(Object obj) {
    if(obj==null)
    return false;
    if(!(obj instanceof A))
    return false;
    A tmp = (A)obj;
    return this.r.nextInt(2)==this.r.nextInt(2);
    }
    }
    }

            5. 非空性:如果(assume)x 不是空,那么 x.equals(null) 应该返回false.

    public class Main {

    public static void main(String[] args){

    Main solution = new Main();

    A a = solution.new A();

    System.out.println(a.equals(null));

    }



    class A{

    @Override

    public boolean equals(Object obj) {

    return true;

    }

    }

    }

    5. equals比较的继承特性,可以先使用super关键字调用父类的比较方法,再书写子类自己的内部逻辑:

    public class Main {
    public static void main(String[] args){
    Main solution = new Main();
    B b1 = solution.new B(5,'a');
    B b2 = solution.new B(6,'a');
    System.out.println(b1.equals(b2));
    }

    class A{
    int item;
    public A(int item){
    this.item = item;
    }
    @Override
    public boolean equals(Object obj) {
    if(obj == null)
    return false;
    if(!(obj instanceof A))
    return false;
    A other = (A) obj;
    return item==other.item;
    }
    }

    class B extends A{
    char c;
    public B(int item,char c){
    super(item);
    this.c = c;
    }

    @Override
    public boolean equals(Object obj) {
    if(!super.equals(obj))
    return false;
    if(!(obj instanceof B))
    return false;
    B other = (B) obj;
    return c==other.c;
    }
    }
    }

    6. 父子类比较希望是false,则需要判断是否同一个类, if(getClass()!=obj.getClass()):

    public class Main {
    public static void main(String[] args){
    Main solution = new Main();
    P p = solution.new P(1);
    A a = solution.new A(1);
    System.out.println(p.equals(a));
    System.out.println(a.equals(p));

    }

    class P{
    protected int a;
    public P(int a){
    this.a = a;
    }
    @Override
    public boolean equals(Object obj) {
    if(obj==null)
    return false;
    if(this==obj)
    return true;
    if(getClass()!=obj.getClass())
    return false;

    P other = ( P)obj;
    return a == other.a;
    }
    }

    class A extends P{

    public A(int a) {
    super(a);
    }

    @Override
    public boolean equals(Object obj) {
    if(obj==null)
    return false;
    if(this==obj)
    return true;
    //都是false?如果期望true怎么办?
    if(getClass()!=obj.getClass())
    return false;

    A other = (A)obj;

    return other.a == this.a;
    }
    }
    }

    7. 父子类希望返回true,必须完全交给父类判断super.equals(obj):

    public class Main {
    public static void main(String[] args){
    Main solution = new Main();
    P p = solution.new P(1);
    A a = solution.new A(1,null);
    System.out.println(p.equals(a));
    System.out.println(a.equals(p));

    P p2 = solution.new P(1);
    A a2 = solution.new A(1,"b");
    System.out.println(p2.equals(a2));
    System.out.println(a2.equals(p2));

    }

    class P{
    protected int a;
    public P(int a){
    this.a = a;
    }
    @Override
    public boolean equals(Object obj) {
    if(obj==null)
    return false;
    if(this==obj)
    return true;
    //当前类没有写extends,无法向上提交,则本层无法进行转换直接判false
    if(!(obj instanceof P)){
    return false;
    }

    P other = ( P)obj;
    return a == other.a;
    }
    }

    class A extends P{
    String s;
    public A(int a,String s) {
    super(a);
    this.s = s;
    }

    @Override
    public boolean equals(Object obj) {
    //先判断再交给父类违背对称性,父类equals会return true
    // if(obj==null)
    // return false;
    // if(this==obj)
    // return true;
    // if(!(obj instanceof A))
    // return s==null && super.equals(obj);
    // A other = (A)obj;
    // return other.a == this.a;
    return super.equals(obj);
    }
    }
    }

    8. 常用覆盖 equals 的类:

  • String/StringBuilder/StringBuffer用于比较字符串是否相等;
  • GregorianCalendar时间参数时区、周起始日等相同
  • Date 毫米级别时间戳相同
  • 包装类(Integer,Double等)比较值是否相等
  • BigInteger/BigDecimal 小数精度要一致,小数能装的下就比较小数,否则转换成数段,进行分段比较
  • 《Java 核心技术 卷1》 笔记 第五章 继承(4)equals方法_后端

      系列内容:

    《Java 核心技术 卷1》 笔记:第一章 Java程序设计概述

    《Java 核心技术 卷1》 笔记:第二章 Java程序设计环境

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(1)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(2)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(3)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(4)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(5)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(6)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(7)大数处理、数组、多维数组、控制台传参

    《Java 核心技术 卷1》 笔记 第四章:类与对象

    《Java 核心技术 卷1》 笔记 第四章:类与对象(2) GregorianCalendar 与 类的基本组成

    《Java 核心技术 卷1》 笔记 第四章:类与对象(3) 构造器全局私有方法

    《Java 核心技术 卷1》 笔记 第四章:类与对象(4) 静态字段+静态方法+工厂方法

    《Java 核心技术 卷1》 笔记 第四章:类与对象(5) 形参与实参 构造器的默认值与默认构造

    《Java 核心技术 卷1》 笔记 第四章:类与对象(6) 构造器调用与初始化块

    《Java 核心技术 卷1》 笔记 第四章:类与对象(7) 注释、JavaDoc与类设计

    《Java 核心技术 卷1》 笔记 第五章 继承

    《Java 核心技术 卷1》 笔记 第五章 继承(2)

    《Java 核心技术 卷1》 笔记 第五章 继承(3)

    喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。

    关注公众号,互相学习:钰娘娘知识汇总

    《Java 核心技术 卷1》 笔记 第五章 继承(4)equals方法_核心技术_02

    网友评论