ADT和OOP中的等价性
Equivalence Relation
ADT 是对数据的抽象,体现为一组对数据的操作
抽象函数AF:内部表示->抽象表示
基于抽象函数AF定义ADT的等价行为
现实中功能每个对象实体都是独特的,所以无法完全相等,有相似性。但是在数学中,绝对相等是存在的
关系等价性:自反,对称,传递
Equality of immutable types
利用AF定义等价性,AF映射到相同的结果,则等价。
利用等价关系引入抽象函数,用抽象函数定义的关系是等价关系
用观察方法定义等价性,站在外部观察者角度,对两个对象调用任何相同的操作,都得到相同的结果,则认为这两个对象是等价的,反之亦然
== vs equals
== 引用等价性
.equals 对象等价性
在自定义ADT需要重写Object 的equals
对基本数据类型,用==判定相等,对对象数据类型,用equals,用==是判断两个对象是不是引用的同一个对象,指向相同的空间
使用@Override标记
Implementing equals()
在Object的实现的缺省equals是在判断引用等价性,因此需要重写
java编译器在选择overload的方法的时候,会采用静态检查(编译时)
在要重写方法时重载方法,很容易在方法签名中出错,
所以只要打算重写超类中的方法,就应该使用Java的注解@Override。
使用此注释,Java编译器将检查具有相同签名的方法是否确实存在于超类中,如果您在签名中犯了错误,则会给您一个编译器错误。
严格来说,在没有AF的情况下,直接判断每个域的等价性,是不正确的
需要进行类型和null值的比较,和比较两个类是不是同一个类
instanceof——动态类型检测,尽量在除了equals里面都不适用,包括getClass等方法也是
使用多态性来避免instanceof
不要再父类中使用instanceof来检测一个子类型
*注意:对子类用父类的检测也正确,比如狗的子类中华田园犬,一个中华田园犬对象ChinaDog instanceof dog 是正确的 *
Object contract
除非对象被修改了,否则多次调用equals的结果相同,相同的对象,hashCode()结果一致
自反(reflexive),传递(transitive),对称(symmetric),equals是一个所有对象之间的全局等价关系
哈希表:映射的一种表示形式:将键映射到值抽象数据类型
hashCode
哈希表 是rep不变形包含一个基本约束,其键位于其哈希代码确定的槽中
hashCode的设计是的秘钥将均匀的分布在索引上
有时候会发生冲突,两个键放在同一个索引中
哈希表不是在索引中保存单个值,而是实际保存一个键/值对列表,通常称为哈希桶
一个键值对在java中时限为一个包含两个字段的对象
插入的时候,将一对添加到有哈希代码确定的数组槽中的列表中
等价的对象必须有相同的hashCode
不相等的对象也可以映射为相同的hashCode,但是性能会变差
标准:将用于确定相等性的对象的每个组件计算一个哈希码(通常是调用每一个对象的hashCode),之后组合起来
Objects.hash(),是的实现包含多个字段的哈希代码变得很容易
Equality of Mutable types
观察等价性:在不改变状态的情况下,两个mutable对象看上去是否一致
行为等价性:调用对象的任何方法都展示出一致的结果
immutable类型的观察等价性和行为等价性相同
对可变类型,往往倾向于实现严格的观察等价性,但有些时候,观察等价性可能会导致bug,甚至可能破坏RI
比如一个Set中的List,在List增加一个元素之后,就不能正确找到了,原因:hashCode改变
如果mutable对象包含在Set集合中,当发生改变之后,集合类的行为不确定
在JDK中,不同的mutable类使用不同的等价类标准
对可变类型,equals实现行为等价性即可,只有指向相同内存空间的objects才是相同的
对可变类型,无需重写equals和hashCode,直接继承Object即可,如果要判断两个可变对象看上去是否一致,最好定义一个新的方法。
Autoboxing and Equality
基本类型有他们的等价的对象类型
将一个基本类型放入Map等集合中的时候会自动装包,取出来的时候是装包后的类型
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!