ADT中的等价性:== VS equals,equals()与hashCode()的重写

1.    ADT是对数据的抽象,体现为一组对数据的操作

       抽象函数AF:内部表示->外部表示

       因此要基于抽象函数AF定义ADT的等价操作

2.    ADT的等价性:

    (1)现实中每个对象实体都是独特的

    (2)所以无法完全相等,但有“相似性”

    (3)而在数学中,绝对相等是存在的

3.    保证等价性的三条方式:

    (1)通过AF:AF若映射到同样的结果,则等价

    (2)通过关系:等价关系是自反,对称,传递的

    (3)通过观察行为:站在外部观察者的角度,调用观察来判定其等价

4.    == VS .equals():

    (1)==是引用等价性,意为两个引用是否指向同一个对象,即同一个内存地址

    (2)equals()是对象等价性,在自定义ADT时,需要对其进行重写,来保证判断其

            等价的条件。

    注: == 对基本数据类型,使用==判定相等 , 对对象类型,使用equals() 

      ( 如果用==,是在判断两个对象 身份标识 ID是否相等(指向内存里的同一段空间) )


5.    重写equals()的方法:

    参数一定为“Object”类型,因为这样是override(重写)

    若为其他类型,则为overload(重载)

    其具有区别:例如:若使用其他参数类型:

    

    则在下列代码中:

    

    明明o2和d2指向同一个对象,但由于引用类型的不同,而java在编译过程匹配Overload的

    方法,d1.equals(o2)调用了未被覆盖的原Object的equals()方法,由于d1,o2指向内

    存地址不同,返回为false。而使用重写方式,覆盖了原Object的equals()方法,

    因此d1.equals(d2)返回为true。

    正确的方式:

    

    注意:1.先判断thatObject是否为Duration的类型,然后再将其转成Duration的引用,

               再将转换后的引用对象调用方法和其进行比较。

6.    重写hashCode():

    规定:(1)若一个对象equal另一个对象,则其hashCode必须(must)相同

              (2)不同的对象,其hashCode应该(should)不同

              (3)HashCode在对象mutate之前不能改变。

    例:以电话号码类为例

            

        hashCode的写法举例:

        

        

   7.    可变类型的观察等价性与行为等价性:

        观察等价性:在不改变状态的情况下,两个mutable对象是否看起来一致 

        行为等价性:调用对象的任何方法都展示出一致的结果 

        (1) 对可变类型来说,往往倾向于实现严格的观察等价性,

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

        例:

        

         这时,

         然而:当之后:

         

         更糟糕的是,在遍历set时,甚至会出现这种情况:

         

        发生的原因:set使用了HashSet的实现方式,其元素的存储位置对应于放入时的

        hashcode。

        而list的hashcode和equals方法的判定是和其内容直接相关的。

        当list内容变化后,其hashcode也变化了,而hashset没有意识到存在原来桶中的元素

        的hashcode与桶不对应,因此hashset去新的hashcode对应的桶中寻找对象,结果没

        有发现,因此出现了错误。

        正如:

        

         (2)因此,对可变类型:

           a. 实现行为等价性即可,也就是说,只有指向同样内存空间的objects,才是相等的。 

           b.所以对可变类型来说,无需重写这两个函数,直接继承 Object对象的两个方法即

            可。

           c. 如果一定要判断两个可变 对象看起来是否一致,最好定义一个新的方法。







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值