2022.05.18 8 Equality in ADT and OOP ADT和OOP中的“等价性”

8 Equality in ADT and OOP ADT和OOP中的“等价性”

Objective of this lecture本章大纲

§ Understand the properties of an equivalence relation. 等价关系
§ Understand equality for immutable types defined in terms of the abstraction function and observations. 站在观察者角度,利用AF,定义不可变对象之间的等价关系
§ Differentiate between reference equality and object equality. 引用等价性和对象等价性
§ Differentiate between strict observational and behavioral equality for mutable types. 可变数据类型的观察等价性和行为等价性
§ Understand the Object contract and be able to implement equality correctly for mutable and immutable types. 理解Object的契约,正确实现等价关系判定

§ Equivalence Relation
§ Equality of Immutable Types
§ == vs. equals()
§ Equality of immutable types
§ The Object contract
§ Equality of Mutable Types
§ Autoboxing and Equality

1 Equivalence Relation

相等就是等价关系中的一个类型

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

2 Equality of Immutable Types

immutable值相等就是等价关系;mutable不能这么比较(可能会发生值的改变)

判断相等时是在A空间判断相等!

a equals b if and only if f(a)=f(b). AF映射到同样的结果,则等价

站在外部观察者角度:对两个对象调用任何相同的操作,都会得到相同的结果,则认为这两个对象是等价的。反之亦然!

比如: Consider the set expressions {1,2} and {2,1}. Using the observer operations available for sets, cardinality |…| and membership ∈, these expressions are indistinguishable:

• |{1,2}| = 2 and |{2,1}| = 2

• 1 ∈ {1,2} is true, and 1 ∈ {2,1} is true

• 2 ∈ {1,2} is true, and 2 ∈ {2,1} is true

• 3 ∈ {1,2} is false, and 3 ∈ {2,1} is false

In terms of ADT, “observation” means calling operations on the objects.

在这里插入图片描述

都对,因为没有针对他们的操作

3 == vs. equals()

在这里插入图片描述

  • For primitives you must use == 对基本数据类型,使用==判定相等

  • § For object reference types 对对象类型,使用equals()

    – The == operator provides identity semantics 如果用==,比较的是行为相等性,是在判断两个对象身份标识 ID是否相等(指向内存里的同一段空间)

    – Exactly as implemented by Object.equals

    – Even if Object.equals has been overridden, this is seldom what you want!

    – You should (almost) always use .equals

  • Using == on an object reference is a bad smell in code

if (input == “yes”) // A bug!!

4 Implementing equals()

在Object中实现的缺省equals()是在判断引用等价性,通常需要重写
在这里插入图片描述

在这里插入图片描述

objects o = S;

objects p = xxx;//泛型

o.equals§;

最终会调用实例化后的equals,没有就是调用objects里的(所以上一题答案是false)

在这里插入图片描述

直接判断每个域的等价性:会进行类型的强转,这是非常不安全的。

(尤其是不能将子类型转换为父类型)

在这里插入图片描述

在这里插入图片描述

5 The Object contract
  • 除非对象被修改了,否则调用多次equals应同样的结果

  • “相等”的对象,其hashCode()的结果必须 一致( 不相等的对象,也可以映射为同样的hashCode,但性能会变差

  • “相等”的对象,应当满足等价关系的三个性质:自反、对称、传递

  • for a non-null reference x , x.equals(null) should return false

  • JAVA对于一些mutable是提供观察者类型的equals(如列表类型LIST);对于一些mutable提供的是引用的相等,如Stringbuilder

  • 用“是否为等价关系”检验你的equals()是否正确

在这里插入图片描述

为避免这种情况,我们需要重写hashCode保证一样的输入获得相同的hashCode;两个equal的objects,一定要 有同样的hashcode

Always override hashCode() when you override equals() 除非你能保证你的ADT不会被放入到Hash类型的集合类中

JAVA一般来讲会自动生成hashCode: Less efficient, but otherwise equally good!(自动生成的hashCode会区分String中的字母大小写!)
在这里插入图片描述

6 Equality of Mutable Type
  • 观察等价性:在不改变状态的情况下(i.e., by calling only observer, producer, and creator methods),两个mutable对象是否看起来一致
  • 行为等价性:调用对象的任何方法(包括mutators)都展示出一致的结果
    (对于immutable来讲,观察等价性等价于行为等价性)
  • 对可变类型来说,往往倾向于实现严格的观察等价性
    ​ - Java uses observational equality for most of its mutable data types (such as Collections), but other mutable classes (like StringBuilder ) use behavioral equality.
    ​ - If two distinct List objects contain the same sequence of elements, then equals() reports that they are equal
    在这里插入图片描述

​ - 这种存在问题,如上图,LIST没法调用到和Set一起引用的同一个值
在这里插入图片描述
在这里插入图片描述

  • 但在有些时候,观察等价性可能导致bug,甚至可能破坏RI(rep invariants )

在这里插入图片描述

  • objects中提供的equals中的方法实现的是行为等价性
  • |A-B|<0.01不满足传递性
  • 相等的判断方法:1、AF(a)==AF(b);2、观察等价性:对于两个对象针对他们所提供的任何方法获得的答案都相同

在这里插入图片描述

(即行为等价性–>

行为等价性:干脆引用一个对象

clone() in Object

§ clone() creates and returns a copy of this object.
§ The precise meaning of “copy” may depend on the class of the
object.
§ The general intent is that, for any object x:
x.clone() != x
x.clone().getClass() == x.getClass()
x.clone().equals(x)
从这些contracts中无法确保是deep copy!

  1. 浅拷贝:对于基本类型->拷贝值;对于对象类型->指向原有的一个引用(只新增引用)
7 基本数据类型的封装(打包)Autoboxing and Equality

封装方式:

  1. ”new":

在这里插入图片描述

  1. “Interger”:number的valueof 最终返回
    在这里插入图片描述
    a.get(“c”).equals(b.get(“c”));:这时候会返回true(👆是false)

单例模式:当值相同时不创建新的对象,指向同一个

(-128~127时使用👇)
在这里插入图片描述
在这里插入图片描述

a.get(“c”).equals(b.get(“c”));:这时候会返回true(👆是false)

单例模式:当值相同时不创建新的对象,指向同一个

(-128~127时使用👇)
在这里插入图片描述

false true(Valueof进行比较)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值