目录
一、相等(Equality)
我们可以从三个角度来看待ADT中的相等:
1.从ADT中的抽象函数AF(abstract function):如果AF(a)=AF(b),我们就说a和b相等。
2.从关系的角度
等价关系是指对于关系E ⊆ T x T ,它满足:
- 自反性: E(t,t) ∀ t ∈ T
- 对称性: E(t,u) ⇒ E(u,t)
- 传递性: E(t,u) ∧ E(u,v) ⇒ E(t,v)
3.从外部观察者角度:对两个对象调用任何相同的操作,都会得到相同的结果,则认为这两个对象是等价的。
二、==与equals()
Java有两种判断相等的操作:==和equals
1.==
==比较的是引用,也就是说,测试的是引用等价性。如果两个索引指向同一块存储区域,那它们就是==的。
2.equals
equals()操作比较对象内容,也就是测试的是对象等价性。
在自定义ADT时,需要重写Object的equals()
3.总结
使用:
对基本数据类型,使用==判定相等
对对象类型,使用equals()。如果用==,是在判断两个对象身份标识ID是否相等(即是否指向内存里的同一段空间)
三、不可变类型的等价性
在Object中实现的缺省equals()是在判断引用等价性,实现如下
public class Object {
...
public boolean equals(Object that) {
return this == that;
}
}
重写与重载
在方法签名中犯一个错误很容易,并且当您打算覆盖它时重载一个方法。
只要你的意图是在你的超类中重写一个方法,就应该使用Java的批注@Override。
通过这个注解,Java编译器将检查超类中是否存在具有相同签名的方法,如果签名中出现错误,则会给出编译器错误。
总结
- 相等应该满足等价关系(自反、对称、传递)。
- 相等和哈希必须互相一致,以便让使用哈希表的数据结构(例如
HashSet
和HashMap
)正常工作。 - 抽象函数是不可变类型相等的比较基础。
- 索引是可变类型相等的比较基础。这也是确保相等一致性和保护哈希表不变量的唯一方法。