等价关系:自反、对称、传递
f(a)=f(b).AF映射到同样的结果,也是等价的。
站在外部观察者的角度,也能判断等价性。
”==“和”equals()“
”==“比较两个对象是否指向相同的储存,就快照图来说,两个对象指向相同的应用。”equals“比较的是对象的内容。在自定义ADT,需要重写equals()。所以对于基本类型,使用”==“判断相等,对对象类型,使用”equals“。
当您重写equals()方法时,您必须遵守其总体合同:
等价关系:自反、对称、传递;
除非对象被修改了,否则调用多次equals应有相同结果;
相等的对象,他的Hashcode()结果必须一致。
自反:对于任何非空参考值x,x.equals(x)必须返回true。
对称:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。
传递:对于任何非空引用值x,y,z,如果x.equals(y)返回true并且y.equals(z)返回true,则x.equals(z)mus返回true。
一致性:对于任何非空引用值x和y,如果修改了在对象上的等值比较中没有使用的信息,则x.equals(y)的多个调用始终返回true或始终返回false。
对于任何非空引用值x,x.equals(null)必须返回false。
equals是所有对象的全局等价关系。
用是否为等价关系可以判断equals是否正确。
散列表是映射的表示形式:将键映射到值的抽象数据类型。哈希表提供了恒定的时间查找,所以它们往往比树或列表执行得更好。密钥不必订购,或具有任何特定的属性,除了提供equals和hashCode。
哈希表如何工作:
它包含一个数组,该数组被初始化为相应的大小
我们希望插入的元素数量。
当提供一个键和一个值用于插入时,我们计算该键的哈希码,并将其转换为数组范围内的索引(例如,通过模分割)。该值然后插入该索引。
哈希表的rep不变量包含密钥在其哈希码确定的时隙中的基本约束。
![](https://i-blog.csdnimg.cn/blog_migrate/079371a4ca386ebe5faa110a1a28c412.png)
不相等的对象,也可以映射为同样的hashCode,但性能会变差。
观察等价性:在不改变状态的情况下,两个可变类型对象是否看起来一致。
行为等价性:调用对象的任何方法都展示出一致的结果。
对于可变类型,往往更倾向于实现严格的观察等价性,但有些时候,观察等价性可能导致Bug,甚至可能破坏RI。
对于可变类型,实现行为等价性即可,无需重写equals和Hashcode函数,直接继承即可,如果一定要判断两个可变对象是否一致,最好定义一个新的方法。
clone与equals关系:
![](https://i-blog.csdnimg.cn/blog_migrate/10428fb925214c84b55eccf5f0140c41.png)