mutable类型数据的等价性可以分为2种:观察等价性和行为等价性
观察等价性:在不改变状态的情况下,两个mutable对象是否看起来一致
行为等价性:调用对象的任何方法都展示出一致的结果
对可变类型来说,往往倾向于实现严格的观察等价性,对不可变类型来说,不存在行为等价性,只存在观察等价性,因为不可变类型不能发生变化。
但在有些时候,观察等价性可能导致bug,甚至可能破坏RI
比如:
加入有一个List,并且把它放入Set:
检查Set是否包含List,结果显然包含:
然后改变List:
结果发现Set里竟然不包含List了!
但我们迭代的时候发现List在Set里面:
那么为什么Set的contains()函数表明List不在SetL里呢?
因为Java中可变类型的改变是会改它的hashCode的,当把List加入Set时,Set记录了当时List的hashCode,但后来List改了之后(add了一个元素),它的hashCode就变了,hashSet的contains()就无法分辨了。