等价性设计原则
可变类
equals() 比较引用,同==运算符。即比较行为等价性而非观察等价性。
hashCode() 将引用地址映射到整型。
不当覆写equals(),hashCode()。
不可边类
equals() 比较抽象值。即比较行为等价性(对不可变类来说,观察等价即行为等价)。
hashCode() 将抽象值映射的整型。
应当覆写equals(),hashCode()。
equals()规范
- 自反性 x.equals(x)==true。
- 对称性 y.equals(x)==true <—> x.equals(y)==true
- 传递性 x.equals(y)==true,y.equals(z)==true —> x.equals(z)==true
- 一致性 若xy引用的对象为变化,则反复调用x.equals(y)的返回值当恒定
- 非空性 x.equals(null) == false
equals()示例
@Override
public boolean equals(Object otherObject)
{
if(this == otherObject)
return true;
//instanceof会检查null;假定所有子类有统一的等价性语义,否则,应手动检查null,并用getClass()检查类型
if(! (otherObject instanceof ImmutableClass) )
return false;
ImmutableClass other = (ImmutableClass) otherObject;
return primitiveFiled1 == other.primitiveFiled1
&& primitiveFiled2 == other.primitiveFiled2
&& Objects.equals(objectFiled1, other.objectFiled1)
&& Objects.equals(objectFiled2, other.objectFiled2);
}
hashCode()规范
- 等价对象必须有相同hash值
- 不等对象应尽可能避免相同hash值
- hash值应当恒定(不可变对象的抽象值恒定,其hash自然恒定;可变对象用地址hash,固也恒定)
覆写equals()时,也应覆写hashCode()
否则,使用基于hash的数据结构时会出现混乱的行为。