一、等价性的判定标准
1.使用AF
两个对象由AF映射到同样的结果,则等价
2.使用observation
对两个对象使用相同的操作得到的结果相同
3.== 和 .equals()的区别
1)== 比较的是引用等价性。对于两个引用,当他们指向内存中的相同的单元时等价。
2).equals()比较的是对象的内容,即对象等价性。注意当我们定义一个ADT时,要根据对对象等价性的要求决定是否重写Object类的.equals()方法
4.== 和 .equals()的使用
1)对基本数据类型,使用==判定相等。基本数据类型中没有.equals()方法。
2)对于对象类型,使用.equals()判定相等。一直使用.equals方法就完事了,因为如果:
a)你想要判断内存地址是否相等,不用override直接用.equals()即可,因为Object.equals()实现时就是用了一个==;
b)如果你有一个判断类相等的逻辑,override过后,那么你还是要用.equals()。
tip:让IDE帮助你override的技巧:
IDEA快速实现接口方法
- Alt + Enter(回车)
- 选择implement methods
- 选择要重写的方法即可
IDEA快速重写父类方法
- 在子类任意想插入的地方按下Ctrl+O即可呼出重写窗口
- 选择重写的方法,OK确认即可
二、instanceof :
instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。且是动态类型检查,不是静态类型检查。注意除了实现.equals方法尽可能避免使用instanceof和getClass方法
三、contract of .equals()
1.对于一个非空引用x,, x.equals(null) should return false。
2.用.equals判定相等的两个对象,其hashcode的值必须相等
3用是否为等价关系检验.equals方法是否正确。(自反,对称,等价,传递,non-nunll,global equivalence先检验,意思是对所有对象都可以比较等价性)
四、Hashcode
1)contract of hashcode
1.程序中多次调用同一个对象的hashcode其返回值必须相同。
2.程序的不同execution的同一对象的hashcode返回值可以不同
3..equals()等价的对象必须有相同的hashcode,但是根据.equals()不等价的两个对象的hashcode可以相同,但是性能会变差
4.因为.equals()等价的对象必须有相同的hashcode,所以如果你override .equals()方法则你必须override hashcode方法
5.
2)overriding hashcode
方法:
1)最简单的方法是让所有对象的hashcode均为同一常量,这样就可以满足规约,但是降低了hashTable效率
2)标准方法:使用.equals()用到的所有信息的hashcode组合出新的hashcode
3)hashcode override example
五、可变数据类型的等价性
1.观察等价性:在不改变状态的条件下,两个对象是否能通过observation辨别。不能则等价
2.行为等价性:任何observation都不能辨别,甚至状态改变,调用对象的任何一种方法都展示出一致的结果。
3.Java对大多数可变数据类型使用观察等价性
4.mutable object 的mutation 会影响 . equas()和hashcode的结果,如果这个object改变,那么它的hashcode也将改变,但是hashset没有更新其位置,查找时在新的hashcode的位置找不到。
一定要当心,当一个可变类型的对象作为一个集合的元素时,当其改变时,集合类行为不确定
注意:可变类型的.equals()应该采用行为等价性标准,即指向相同的内存单元,因此无需override .equals 和hashcode 函数,直接从Object类继承即可。
如果一定要判断两个可变数据类型对象是否看起来相等,最好定义一个新method
5.总结:1.不可变数据类型:要override .equals和 hashcode
2.可变数据类型: 直接用Object默认的equals 和hashcode
六 clone
七 Autoboxing and Equality
1.Integer 的equals是比较值
2.数字-128~127满足引用等价性



