重新定义equals方法时,一定要一起重新定义hashCode方法,以便用户可以将对象插入到散列表中
1. 显示参数命名为otherObject,稍后需要将它进行类型转换,转换为另一个叫做other的变量
2. 检测this与otherObject是否引用同一个对象
这条语句是一个优化,因为计算这个等式要比一个一个地比较类中的域所付出的代价小的多。(如果一个对象是另一个对象的clone,这样比好像没有意义吧)
3. 检测otherObject是否为null,如果为null,返回false。这项检测是很有必要的
4. 比较this与otherObject是否属于同一个类
- 如果equals的语义在每个子类中有所改变,就使用getClass检测:
if(getClass( )!=otherObject.getClass())return false;
- 如果所有子类都用于同一的语义,就使用instanceof检测:
if(!otherObject instacenof ClassName)return false;
5. 将otherObject转换为相应类的类型变量
ClassName other = (ClassName)otherObject
6. 现在开始对对所有需要比较的域进行比较,使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,则返回true,否则返回false
return field1 ==other.field1 && Objects.equals(field2,other.field2)&& ...;
如果在子类中重新定义equals,就要在其中包含调用super.equals(other)
Tips:对于数组类型的域,可以使用静态的Arrays.equals方法来检测相对于的数组元素是否相等
使用null安全方法Objexcts.hachCode,如果参数为null,这个方法返回0,否则返回对参数调用hashCode的结果:
public int hashCode(){
return 7* Objects.hashCode(name)+11*new Double(age).hashCode();
}
需要组合多个散列值时,可以调用Objects.hash方法:
public int hashCode(){
return Objects.hash(name,age);
}
equals与hashCode定义必须一致,如果x.equals(y)返回true,那么x.hashCode()就必须与y.hashCode()具有相同的值。
Tips:如果存在数组类型的域,那么可以使用静态的Arrays.hashCode方法计算一个散列值,这个散列值由数组元素的散列值组成