等价关系
在这里我们把离散数学当中的等价性引入了ADT中。在离散数学中等价关系满足三条性质,即:自反性、对称性、传递性。自反性
∀t∈ \in∈T, t R t.
对称性
∀u,v∈ \in∈T, if u R v, then v R u.
传递性
∀u,v,w∈ \in∈T, if u R v, and v R w, then u R w.
不可变类型的等价性
我们可以利用抽象函数来判断两个对象是否等价,如果两者的AF映射会得到同样的结果,那么说明二者等价,否则,他们不是等价的。
“==”和vs.equals区别
==说的其实是引用等价,在java中,引用和C语言中的指针类似,指向一个内存空间。如果二者的引用等价,这说明这两个对象在内存中的地址是一样的。因此,我们认为二者是等价的。equals()是java中Object中定义的一个等价方法。缺省也是比较引用相等的。但是java的开发者对于类型特定的数据结构重写了equals方法。我们在编程过程中往往也需要重写equals()
如下图,这是一个较好的方法重写了equals函数,将原本默认通过引用等价判断两个对象等价替换为通过Duration的长度是否相等来判断等价类。

要注意的是,在这里我们使用了instanceof函数,这个函数的使用应该谨慎。除了实现等号,例如instanceof、getclass这种对象运行时的方法都应该被禁止。
HashCode方法
在我们重写了equals方法的时候,往往要求我们重写hashcode方法。否则的话很可能产生一些令人难以察觉的bug。
同时,要注意的是,有时候不同的对象也会有相同的hashcode值。
默认的hashcode是返回this的内存地址。当然你可以设置每一个对象的hashcode返回一个值。但这样所有的对象都被放在了一个槽中,这回导致程序的性能大大降低。
观察等价性和行为等价性
观察等价性:在不改变状态的情况下【也就是没有调用mutator方法】,两个mutable对象是否看起来一致
行为等价性:调用对象的任何方法都展示出一致的结果【这个的要求比观察等价性更高一些,要求在状态改变的时候也无法分辨出来】
设计准则
对于可变类型,实现行为等价性,只有指向同样内存空间的object才是相等的
所以对于可变类型,不需要重写这两个函数
如果一定要判断两个变量看起俩是否一致,最好定义一个新的方法
9916

被折叠的 条评论
为什么被折叠?



