第八章 ADT和OOP中的 “等价性“

第八章 ADT和OOP中的 “等价性”

等价关系

  • 自反、对称、传递

== vs. equals()

Java的两种操作测试等价性

==

  • == 运算符比较引用。 它测试引用相等性。 如果两个引用指向内存中的相同存储,则它们是 ==。 就快照图而言,如果两个引用的箭头指向同一个对象气泡,则它们是 ==。
  • 基本数据类型必须使用==
  • 对象数据类型如果用==,是在判断两个对象身份标识 ID是否相等(指向内存里的同一段空间)

equals()

  • 比较对象内容

  • 当我们定义一个新的数据类型时,我们有责任决定对象相等对于数据类型的值意味着什么,并适当地实现 equals() 操作。

  • 定义在Object中,默认实现方法是return this==that,即判断引用等价性

  • 重写方法

    • 注意:参数一定要是Object,否则在一些泛型方法中可能会出问题,而且不能跨类型比较,即使是同一类型的强转。(避免这种错误可以用@override修饰)
    • 步骤 判null、利用instanceof或getClass()判类型、最后根据AF判相等
    • 除了equals方法外,避免使用instanceof和getClass(),可以用多态来代替
  • 重写equals方法遵循的原则

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

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

    • 对于非空引用 x , x.equals(null) 应该返回 false;

    • 除非你能保证你的ADT不会被放入到Hash类型的集合类中,否则一定要重写hashCode()

    • “相等”的对象,其hashCode()的结果必须一致

      • 如果两个相等的对象具有不同的哈希码,则它们可能被放置在不同的插槽中。因此,如果尝试使用与插入时相同的键来查找值,则查找可能会失败。Object 的默认 hashCode() 实现与其默认的 equals() 一致,即返回对象内存中的地址
    • 不相等的对象,也可以映射为同样的hashCode,但性能会变差

Immutable类型的等价

使用AF

  • AF映射到同样的结果,则等价

    • 从用户的角度看

观察等价性

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

AF和观察等价性判断出来的结果可能不同

  • 这种AF相等,但是观察等价性判定不相等的观察器应该避免存在

Immutable类型观察等价性和行为等价性一致

  • 因为没有任何mutator方法

建议

  • 一定要重写equals()和hashCode()

Mutable类型等价性

观察等价性

  • 当无法通过不改变对象状态的观察来区分它们时,即仅调用观察者、生产者和创建者方法。

  • 某个时间点

  • 当mutable类型使用观察等价性可能会出错

    • HashSet

行为等价性

  • 调用对象的任何方法都展示出一致的结果

  • 时间段

    • 此状态和未来所有状态
  • 只有指向相同的内存空间的对象才是相等

建议

  • 对可变类型,实现行为等价性即可
  • 无需重写equals()和hashCode(),直接继承Object 的两个方法即可。
  • 可以定义一个新方法similar()来判断观察等价性

示例

  • 在这里插入图片描述

Java自动装箱

  • Java基本数据类型在一些情况下会自动装箱,例如,在使用基本数据类型作为泛型时List l=new ArrayList<>();l.add(1);这里1被装箱了,若两个装箱的对象前加(int)强转就会自动拆包

  • 装箱后变成一个对象,应该使用equals()进行比较,使用==会判断是否是同一个引用

单例模式

  • 如果对象不存在,就会创建对象,如果对象存在就会直接应用同一个对象

  • 注意:new 对象 不会使用单例模式

  • 字符串和-128到127之间的整数会使用单例模式

  • 示例

    • 在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值