等价方法的传递性

Bha*_*kar 32 java

equals(object)方法的契约指定了要遵循的4个属性:自反,对称,传递和一致.虽然我理解不遵循Reflexive,Symmetric和Consistent的危险,并且肯定会同意其传递的好处,但我想知道如果违反Transitive属性会带来什么伤害?

具体来说,哪个Java库(或各种第三方库)需要依赖equals才能传递才能正常工作?根据我的理解,如果其他3个属性得到很好的实现,Collections框架将会起作用.

phi*_*hag 42

假设有三个对象a,b,c

a == a, b == b, c == c (reflexive)
a == b, b == a
b == c, c == b
a != c, c != a
Run Code Online (Sandbox Code Playgroud)

(伪代码,x == y代表x.equals(y)).

现在,让我们将对象添加到集合中:

Set s = new HashSet(); // Set implementation doesn't matter
s.add(b); // s = [b]
s.add(a); // s doesn't change, because a == b
s.add(c); // s doesn't change, because c == b
Run Code Online (Sandbox Code Playgroud)

相反,如果我们以不同的顺序添加它们:

Set s = new HashSet();
s.add(a); // s = [a]
s.add(b); // s doesn't change, because b == a
s.add(c); // s = [a,c], because c != a
Run Code Online (Sandbox Code Playgroud)

这显然是违反直觉的,并且与人们对集合的预期行为不匹配.例如,这意味着两个集合的联合(即后面的s的状态s.addAll(someOtherSet))可能取决于someOtherSet的实现(元素的顺序).

  • @Gandalf我不会.让它变得更加复杂和复杂,我认为;)很好的例子. (2认同)

Gan*_*alf 9

目前我不知道Java API存在传感性缺失的问题.(我还在反思一个例子).

但与此无关,平等需要传递性,因为这是等式关系的数学代数定义.http://en.wikipedia.org/wiki/Equality_(mathematics)

如果不存在传递性,则不得将该方法称为等于,因为考虑到听到/读取"平等"时的期望,这会产生误导.这与最不惊讶的原则相矛盾.http://en.wikipedia.org/wiki/Principle_of_least_astonishment

[编辑]

有趣的是,严格的数学说法是java equals方法定义的"相等"不是平等,而是更一般的等价关系http://en.wikipedia.org/wiki/Equivalence_relation,因为不同的对象也可以是根据java,"相等",因此与真正平等所需的反对称属性相矛盾.

结论:

Java中的.equals是一种等价关系(仍然需要传递性)

Java中的==是一种相等(或同一性)关系