Transitive nature of equals method

前端 未结 4 1172
一个人的身影
一个人的身影 2020-12-09 15:23

The contract for equals(object) method specifies 4 properties to follow: Reflexive, Symmetric, Transitive and Consistent. While I understand the danger of not f

相关标签:
4条回答
  • 2020-12-09 16:00
    Integer a = new Integer(1);
    Integer b = new Integer(1);
    

    a == 1 is true, b == 1 is true but, a == b is not true.

    0 讨论(0)
  • 2020-12-09 16:02

    At the moment I am not aware of a Java API that has problems with the absence of transitivity. (I am still reflecting for an example).

    But independent of that, transitivity is required for equality because that is the mathematical algebraical definition of the equality relation. http://en.wikipedia.org/wiki/Equality_(mathematics)

    If transitivity is not present the method must not be called equals because this would be misleading taking into account the expectation one has when hearing/reading "equality". This would contradict the principle of least astonishment. http://en.wikipedia.org/wiki/Principle_of_least_astonishment

    [EDIT]

    The interesting thing about this is that strictly mathematical speaking the "equality" defined by the java equals method is not an equality but rather the more general equivalence relation http://en.wikipedia.org/wiki/Equivalence_relation because different objects can also be "equal" according to java, thus contradicting the antisymmetry property required for a true equality.

    Conclusion:

    .equals in Java is a equivalence relation (which still requires transitivity)

    == in Java is an equality (or identity) relation

    0 讨论(0)
  • 2020-12-09 16:12

    Assume three objects a,b,c with

    a == a, b == b, c == c (reflexive)
    a == b, b == a
    b == c, c == b
    a != c, c != a
    

    (Pseudocode, x == y stands for x.equals(y)).

    Now, let's add the objects to a set:

    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
    

    In contrast, if we were to add them in a different order:

    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
    

    That is clearly counter-intuitive and doesn't match the behavior one would expect of a set. For example, it would mean that the union of two sets (i.e. the state of s after s.addAll(someOtherSet)) could depend on the implementation (order of elements) of someOtherSet.

    0 讨论(0)
  • 2020-12-09 16:17

    Consider Object a == b == c with a != c ( non transitive equality )

    First problem would be hashcode() contract which requires that hashcodes are equal if objects are equal. And you will be able to add a and c to the same set - this can lead to subtle problems in unexpected places

    0 讨论(0)
提交回复
热议问题