0
点赞
收藏
分享

微信扫一扫

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


5.2.1 equals 方法

形式

public void equals(Object object){}

注意点:

  1. 参数类型不能修改,如果不写Object 那就是方法重载,不是方法重写;
  2. 当前类不进行方法重写,且非Object 的其他父类不进行方法重写时,比较的是两个对象的地址,及两个变量是否指向同一个对象;
  3. 进行方法重写时(未使用extends继承已覆盖equals的父类),通常需要几个步骤:
  1. 判断是否为空,为空的情况下必然不相等(否则调用前空指针)
  2. 判断是否是同一个对象,是同一个对象必然相等
  3. 使用intanceof判断能否进行类型账号,不能转换必然不相等
  4. 进行类型转换后比较相应的值
  1. equals比较的规则,来自Thinking in Java
  1. 自反性:自己和自己比较必然返回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,那么不修改ab的情况下无论调用多少次结果都应该一样;反例:

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 的类:

  1. String/StringBuilder/StringBuffer用于比较字符串是否相等;
  2. GregorianCalendar时间参数时区、周起始日等相同
  3. Date 毫米级别时间戳相同
  4. 包装类(Integer,Double等)比较值是否相等
  5. 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

举报

相关推荐

0 条评论