5.2.1 equals 方法
形式:
public void equals(Object object){}注意点:
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 的类:
系列内容:
《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)
喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。
关注公众号,互相学习:钰娘娘知识汇总