equals 方法具有一些自身的特定:
1、自反性:x.equals(x)返回true;
2、对称性:若x.equals(y)为true,则y.equals(x)亦为true;
3、传递性:若x.equals(y)为true且y.equals(z)也为true,则x.equals(z)亦为true;
4、一致性:x.equals(y)的第一次调用为true,那么x.equals(y)的第二次、第三次、第n次调用也均为true,前提条件是没有修改x也没有修改y;
5、对于非空引用x,x.equals(null)返回为false。
这些规则看起来很简单,似乎我们怎么重写eqauls 方法都不会违反这些规则。实际上我们有时候就在这些细微的地方引入的严重的bug
写道
public class A {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof A) {
return ((A) obj).name.equalsIgnoreCase(name.trim());
}
return false;
}
}
运行的结果发现他可能连自己都不认识的。
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof A) {
return ((A) obj).name.equalsIgnoreCase(name.trim());
}
return false;
}
}
写道
public class Test {
public static void main(String[] args) {
A a = new A();
A b = new A();
b.setName("Test");
a.setName(" Test");
boolean r = a.equals(b);
System.out.println(r);
System.out.println(b.equals(a));
}
}