[软件构造]相等

三种“相等”的方式

抽象函数:抽象函数将具体的数据映射到抽象的值,如果AF(a)=AF(b),我们就说a和b相等。

等价关系:等价是指对于关系E\subseteq T x T,满足自反性,对称性,传递性。则我们说a等于b当且仅当E(a,b)。

观察:两个对象a和b相等当且仅当使用者无论怎样观察总会得到相同的结果。

== vs .equals()

==比较的是索引。如果两个变量==,那么它们指向同一块存储区域,在快照图中展现为它们的箭头指向同一个对象。

.equals()操作是比较对象的内容。比较的是两个对象的值是否相等。equals方法在是在object方法下定义的,在每个ADT中,都必须对equals函数进行相应的定义。

不可变类型的相等

equals() 是在 Object 中定义的,它的(默认)实现方式如下:

public class Object {
    ...
    public boolean equals(Object that) {
        return this == that;
    }
}

equals() 在Object中的实现方法就是测试指向/索引相等。对于不可变类型的对象来说,这几乎总是错的。所以你需要覆写equals() 方法,将其替换为你的实现。

对象契约

object中有equal的规格说明。当我们在覆写equals时,要记得遵守这些规定:

1.equals 必须定义一个等价关系。即一个满足自反性、对称性和传递性关系。

2.equals 必须是确定的。即连续重复的进行相等操作,结果应该相同。

3.对于不是null的索引x, x.equals(null) 应该返回false。

4.如果两个对象使用 equals 操作后结果为真,那么它们各自的hashCode 操作的结果也应该相同。

可变类型的相等

与不可变类型相比,可变类型可以通过在观察前调用改造者,我们可以改变其内部的状态,从而观察出不同的结果。

所以让我们重新定义两种相等:

  • 观察相等:两个索引在不改变各自对象状态的前提下不能被区分。例如,只调用观察者、生产者、创建者。它测试的是这两个索引在当前程序状态下“看起来”相等。
  • 行为相等:两个所以在任何代码的情况下都不能被区分,即使有一个对象调用了改造者。它测试的是两个对象是否会在未来所有的状态下“行为”相等。+

对于不可变对象,观察相等和行为相等是完全等价的,因为它们没有改造者改变对象内部的状态。

对于可变对象,Java通常实现的是观察相等。但这可能会导致一些非常隐蔽的bug。事实上,对可变类型而言,equals应该实现行为相等,可惜java并没有进行这样的设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值