3.5 Equality in ADT and OOP
等价性equals()和==
1、== 引用等价性
- == 对基本数据类型,使用==判定相等
- 如果用==,是在判断两个对象身份标识 ID是否相等(指向内存里的同一段空间)
2、equals() 对象等价性
- 在自定义ADT时,需要重写Object的equals()
- 对对象类型,使用equals()
Equality of immutable types 的重写override 和 重载overload
首先,在Object中实现的缺省equals()是在判断引用等价性,通常不是程序员所期望的
![](https://i-blog.csdnimg.cn/blog_migrate/ddb8f4019fdbc5ea8e78e42815ddbda7.jpeg)
所以需要重写,有两种方式
1、overload
![](https://i-blog.csdnimg.cn/blog_migrate/f31bc0fa867470c3228c728b11cdb80f.jpeg)
直接使用这个equal()来实现下面的代码会出错
![](https://i-blog.csdnimg.cn/blog_migrate/4f4b0f4893a193ea69afc7d29f0fde06.jpeg)
这样进行改进
![](https://i-blog.csdnimg.cn/blog_migrate/6d53f09ee6f07293698da5045d12848e.jpeg)
2、Override
![](https://i-blog.csdnimg.cn/blog_migrate/a2dc85dba2d2200117608d8f3deded2f.jpeg)
参数类型仍未Object,所以这是override
意义在于
先判断thatObject是否为Duration的类型,然后再将其转成Duration的引用,再将转换后的引用对象调用方法和其进行比较。
equals()的自反、传递、对称
![](https://i-blog.csdnimg.cn/blog_migrate/0e618712c6936a26a108f39afc01db7b.jpeg)
hashCode()
1、两个被认为equal的对象hashcode应该相同;
override equal()必须重写hashcode
2、unequal的对象hashcode不能相同
3、Hash code must not change unless object mutated
继续以上例为例
![](https://i-blog.csdnimg.cn/blog_migrate/cbd5832715330fcaf188f4b720513e0c.jpeg)
可变对象的观察等价性、行为等价性
观察等价性:在不改变状态的情况下,两个mutable对象是否看起来一致
行为等价性:调用对象的任何方法都展示出一致的结果
对可变类型,实现行为等价性即可。也就是说,只有指向同样内存空间的objects,才是相等的。
所以对可变类型来说,无需重写这两个函数,直接继承Object对象的两个方法即可。
如果一定要判断两个可变对象看起来是否一致,最好定义一个新的方法。
可变不可变对equals()和hashcode()的比较
不可变
|
可变
|
equals()实现行为等价性
|
equals()在实现引用等价性==的基础上实现行为等价性
|
hashcode()把abstrract value映射成一个整数
|
hashcode()把引用映射成一个整数
|
equals()改变必须重写hashcode()
|
equals()改变无需重写hashcode()
|