JDK提供的工具类
Object :: equals
public boolean equals(Object otherObj){
return this == otherObj;
}
比较存储地址是否相等。
String :: equals
public boolean equals(Object anObj){
if(this == anObj) return true;
if( anObj instanceof String ) { // 如果anObj为null,instanceof为false; // String 为final的没有子类,因此适合用instanceof
String other = (String) anObj;
int n = value.length;
if( n == other.value.length){
char [] v1 = value;
char [] v2 = other.value;
int i=0;
while( n--!=0 ){
if(v2[i]!=v2[i]) return false;
i++;
}
return true;
}
}
return false;
}
Objects :: equals
public static boolean equals(Object a,Objectb){
return (a==b) || (a!=null) && a.equals(b);
}
自定义类的equals方法一般实现
- 如果有父类的实现,首先
if(!super.equals()) return false;
- 如果没有父类,首先
if( this == otherObj) return true;
- 如果没有父类,再判断
if(otherObj == null ) return false;
- 如果没有父类,并且当前类不是fianl的,用
if( !(getClass()==otherObj.getClass())) return false;
判断是否相同类型 - 最后对两个对象的域的值进行判断,对于复杂数据类型的域,要用Objects.equals(a,b)去比较,以防NullException
- 根据Object类对equals方法的定义的逆反性规则,如果类不是final的,用if( getClass() == other.getClass())比较两者是否同一个类,而非用instanceof来判断。原因:
规则要求:a.equals(b) <=> b.equals(a) ;即如果a.equals(b)为true,那么必然b.equals(a)也为true;
在这种规则下,假如有类B是A的子类(class B extends A
),又有A的实例a,B的实例b,
如果用instanceof:
- a.equals(b)有可能为true。因为B是A的子类,b instanceof A为true。
- 而b.equals(a)则一定为flase。因为A是B的父类。因此a instanceof b 一定为false
- 如此,则不能实现可逆规则。
class A { ... if( otherObj instanceof A) ...}
class B extends A { ... if( otherObj instanceof B) ...}
实例:
/**
雇员类
*/
public class Employee{
private String name;
private double salray;
private LocalDate hireDay;
...
public boolean equals(Object otherObj){
if(this == otherObj) return true;
if(otherObj == null) return false;
if(getClass() == otherObj.getClass()){
Employee other = (Employee)otherObj;
return Objects.equals(name,other.name) &&
(salary == other.salary) &&
Objects.equals(hireDay, other.hireDay)
}
return false;
}
}
/**
管理人员
*/
public class Manager extends Employee{
private double bonus; // 绩效奖金
...
public boolean equals(Object otherObj){
if(!super.equals(otherObj)) return false;
Manager other = (Manager)otherObj;
return bonus == other.bonus;
}
}