override equals方法的几个原则
-
自反性。对于任何非null的引用值x,x.equals(x)应返回true。
-
对称性。对于任何非null的引用值x与y,当且仅当:y.equals(x)返回true时,x.equals(y)才返回true。
-
传递性。对于任何非null的引用值x、y与z,如果y.equals(x)返回true,y.equals(z)返回true,那么x.equals(z)也应返回true。
-
一致性。对于任何非null的引用值x与y,假设对象上equals比较中的信息没有被修改,则多次调用x.equals(y)始终返回true或者始终返回false。
示例代码(String类的equals方法):
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- list中的indexOf,contains方法根据equals方法来判断对象是否相等
override hashCode方法
从Object类中的源码可以看到重载equals之后需要重载hashCode的提示
If two objects are equal according to the {@code equals(Object)}
* method, then calling the {@code hashCode} method on each of
* the two objects must produce the same integer result.
- String 类的hashCode代码:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
- Map接口会使用,可以简单理解为通过hashCode方法算出该变量的地址,那么当两个变量相等,那么这个算出来的hashCode也势必需要相等.
编写equals的建议
下面给出编写一个完美的equals方法的建议(出自Java核心技术 第一卷:基础知识):
-
显式参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量(参数名命名,强制转换请参考建议5)
-
检测this与otherObject是否引用同一个对象 :if(this == otherObject) return true;(存储地址相同,肯定是同个对象,直接返回true)
-
检测otherObject是否为null ,如果为null,返回false.if(otherObject == null) return false;
-
比较this与otherObject是否属于同一个类 (视需求而选择)
-
如果equals的语义在每个子类中有所改变,就使用getClass检测 :if(getClass()!=otherObject.getClass()) return false; (参考前面分析的第6点)
-
如果所有的子类都拥有统一的语义,就使用instanceof检测 :if(!(otherObject instanceof ClassName)) return false;
-
-
将otherObject转换为相应的类类型变量:ClassName other = (ClassName) otherObject;
-
现在开始对所有需要比较的域进行比较 。使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,就返回true,否则就返回flase。
-
如果在子类中重新定义equals,就要在其中包含调用super.equals(other)
-
当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明 相等对象必须具有相等的哈希码 。