这个合集本来都准备半途而废了。结果在刷题的过程中又遇等价,那不如来简单总结一下吧。
1.等价的三种表达形式
a.抽象函数
f: R → A
a等价于b 当且仅当 f(a)=f(b)
b.相等的数学表达
满足自反性,对称性和传递性。
c.观察法
一种判定性方法,即对两个集合或两个元素调用任何操作得到的结果都是一样的。
2.== vs equals()
== 引用相等(指向相同的内存)
equals() 对象相等(对象包含的内容相同)
3. 不可变类型的equals方法重写
默认写法:
public class Object {
...
public boolean equals(Object that) {
return this == that;
}
}
这种写法若不重写对于不可变类型来说基本是错误的,和引用相等是等价的。
一个不可变的抽象数据类型(ADT)的例子:
public class Duration {
private final int mins;
private final int secs;
/** Make a duration lasting for m minutes and s seconds. */
public Duration(int m, int s) {
mins = m; secs = s;
}
/** @return length of this duration in seconds */
public long getLength() {
return mins*60 + secs;
}
}
重写它的equals方法:
@Override
public boolean equals (Object thatObject) {
if (!(thatObject instanceof Duration)) return false;
Duration thatDuration = (Duration) thatObject;
return this.getLength() == thatDuration.getLength();
}
测试结果:
Duration d1 = new Duration(1, 2);
Duration d2 = new Duration(1, 2);
Object o2 = d2;
d1.equals(d2) → true
d1.equals(o2) → true
注:instanceof
除了在重写equlas方法时,其他时候都是不推荐使用的。
4. Object类重写equals方法必须满足的规则
a.满足三个数学特性:自反性,对称性,传递性。
b.对于非空引用x
,x.equals(null)
返回false
c.应具有一致性,多次调用方法的返回结果应该一样/
d.对于调用equals
方法返回为true
的对象,其对应的哈希值应该是一样的。
因为哈希值与实际的存储插槽有关,如果两个对象的哈希值不同,存放的插槽也会不同。
规则:Always override hashCode when you override equals .
对于不可变类型,需要重写
equals()
和hashCode()
。
对于不可变类型,则不需要。