1.Immutable类型的等价性
策略
根据值判断相等,因为Immutable类型的数据的值定了,就不能改变值。
AF等价性
如果两个对象AF映射到同样的结果,则认为是等价的。
观察者等价性
使用observer方法判断相等,如果两个对象调用任何相同的操作,都会得到相同的结果,则认为是等价的。
由于用户是看不见AF的,因此对于Immutable 类型的对象采取观察者等价性较为合理。
2.mutable类型的等价性
策略
观察者等价性
在不改变状态的情况下,使用observer方法判断相等,如果两个对象调用任何相同的操作,都会得到相同的结果,则认为是等价的。
行为等价性
调用对象的任何方法都展示出一致的结果,意味着两个对象实际上就是一个对象。
由于mutable类型变量的值会变,如果采用Immutable类型变量以值判断相等,既采用观察者等价性的策略,则会出现BUG。两个对象可能在不同时刻,各会出现相等和不相等的情况。
例:对象A和B为两个mutable类型的同一个类型的对象,但是A和B的引用指向不同的对区域,既A和B不是同一个对象。
如果某个时刻A和B中的状态相等,则根据观察者等价性,A和B两个对象是相等。
若A调用了mutator操作,修改了A中的某个状态,而B不动,则此时根据观察者等价性,A和B两个对象又不相等。
有了BUG:出现了两个对象有时相等,有时又不相等的情况。
因此,对于mutable类型变量,往往倾向于实现严格的行为等价性,既两个对象的引用指向相同的内存空间。
而由于观察者等价性和行为等价性的定义,对于immutable类型的变量,观察者等价性和行为等价性是等价的。
3.==与equals()方法判断相等
3.1 ==(引用等价性)
对于基本数据类型,比较值是否相等;
而对于对象类型,判断两个对象的ID是否相等,既指向相同内存空间的对象才相等。
基本数据类型判断相等使用==。
3.2 equals()方法
3.2.1 Object中的equals()方法
public boolean equals(Object that){
return this == that;
}
根据代码看到,Object中的equals()方法就是通过==判断相等,这不是我们所希望的。因此,在我们自定义ADT时,需要重写equals()方法。
但是在JAVA中,若改变了equals()方法参数的类型,则就是overload而不是override。
例:
//overload,若在前面加上@Override,编译器会报错
public boolean equals(MyObject that){
//to do
}
@Override
public boolean equals(Object that){//不能改变Object
//to do
}
3.2.2 instanceof
用来测试一个对象是否为一个类的实例
boolean result = obj instanceof Class
3.2.3 equals()方法的规约
1.满足自反、传递、对称;
2.除非对象被修改了,否则调用多次的equals()方法应当一致;
3.obj.equals(null);应当返回为false;
4.判断相等的对象,其hashCode()的结果必须一致。
对于第四条要求,我们最好应当满足:相等的对象,hashcode一样;不相等的对象,hashcode不一样。
3.2.4 Object中的hashCode()方法
public boolean hashCode(){
return /*the memory address of this*/;
}
为了满足相等的对象,hashcode一样的要求,我们需要对自定义ADT的hashCode()方法进行重写。
除非能够保证自定义的ADT是永远不会被放入到Hash类型的集合中,但是这个条件难以满足。