软件构造笔记5

等价关系
自反、传递、对称

immutable types的等价性
如果AF映射到同样的结果,则等价
这里区分引用等价和对象等价

== vs. equals()
==说的是引用等价,说的是两个引用指向了相同的内存空间
equals()说的是对象等价,说的是两个对象的field是相同的

重写equals方法
在自定义ADT时需要重写object的equals方法
在object中实现的equals方法是在判断引用等价性
就像这样:在这里插入图片描述

 

但是这个例子不是重写,而是重载,这个时候其实我们就有两个equals方法,是静态分派了

在这里插入图片描述

 

更好的方法

在这里插入图片描述
instanceof
instanceof用于判断某个子类是不是某个类的对象
是动态检查
除了equals方法,任何地方都不应该使用

 

object的契约
关于equals方法
equals必须定义一个等价关系
x.equals(x) 返回值为true
x.equals(y) 和y.equals(x) 返回值必须一样
传递关系一样的道理
调用多次equals方法应该得到同样的结果
x.equals(null) 的返回值必须是null
有一点需要保证,就是hashcode方法必须和equals方法是同步的,也就是说两个对象相等的时候必须有相同的hashcode返回值

关于hashcode方法
等价的对象必须有相同的hashcode【也就是说如果你重写了equals方法,就必须重写hashcode方法】
不相等的对象,也可以映射为同样的hashcode,但性能会变差【也就是说不相同的对象应该有不同的哈希码】
如果object没有被mutate,那么它的哈希码不能被更改
如果两个相同的对象的哈希码不一样的话,那么将他作为key进行查找的时候就有可能计算出两个哈希值,那么就会查找失败
默认的哈希值是this的内存地址
如果返回一个常量,是符合equals的标准的,但是,所有的存贮对象都会记载一个槽里,这样会增加搜索时间

equality of mutable types
当通过观察无法区分两个对象的时候,我们就说这两个对象是等价的
这里分观察等价性和行为等价性
观察等价性:在不改变状态的情况下【也就是没有调用mutator方法】,两个mutable对象是否看起来一致
行为等价性:调用对象的任何方法都展示出一致的结果【这个的要求比观察等价性更高一些,要求在状态改变的时候也无法分辨出来】
note:对于immutable类型的对象来说,这两个等价性是相同的,因为没有mutator方法

在java中
对可变类型来说,往往倾向于实现严格的观察等价性
但是在有些时候,观察等价性可能导致bug,甚至可能破坏RI(当equals和hashcode可能被改变的时候,可能RI就被改了)
提示:如果某个mutable的对象包含在集合类中,当其(指的是这个对象)发生改变后,集合类的行为不确定
在jdk中,不同的mutable类使用不同的等价性标准(比如collections使用的是观察等价,其他的类比如stringbuilder使用的是行为等价)

设计准则
对于可变类型,实现行为等价性,只有指向同样内存空间的object才是相等的
所以对于可变类型,不需要重写这两个函数
如果一定要判断两个变量看起俩是否一致,最好定义一个新的方法
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值