Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transitive nature of equals method

Tags:

java

The contract for equals(object) method specifies 4 properties to follow: Reflexive, Symmetric, Transitive and Consistent. While I understand the danger of not following Reflexive, Symmetric and Consistent , and can definitely agree its good to follow transitive, I was wondering what harm it would bring if its violating the Transitive property?

Specifically, which of the Java library (or various third party libraries) need the dependency upon equals to be transitive to work correctly? In my understanding, the Collections framework will work if the other 3 properties are well implemented.

like image 708
Bhaskar Avatar asked Oct 08 '11 13:10

Bhaskar


People also ask

Is transitive equal?

equals(x) returns true. It is transitive: for any reference values x, y, and z, if x. equals(y) returns true and y. equals(z) returns true, then x.

What is equals () method in Java?

Java String equals() Method The equals() method compares two strings, and returns true if the strings are equal, and false if not. Tip: Use the compareTo() method to compare two strings lexicographically.

Which of the following implies that the equals () method is reflexive?

The equals() method must be: reflexive: An object x must be equal to itself, which means, for object x, equals(x) should return true. symmetric: for two given objects x and y, x. equals(y) must return true if and only if equals(x) returns true.

What is the hashCode () and equals () used for?

So while the equals() function first checks if two objects are the same and then compares the value of the objects' attributes, the hashCode method compares them by using only their hash codes and gives us a conclusion. It is used for more efficient storage of data by collections. This facilitates quicker access.


2 Answers

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.

like image 122
phihag Avatar answered Oct 19 '22 05:10

phihag


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

like image 21
Gandalf Avatar answered Oct 19 '22 07:10

Gandalf