Pranshul Bajaj

Greenhorn

Posts: 7

posted 4 months ago

It looks like if you implement Comparable for sorting, you should override equals() to, although this is not technically necessary.

Javadoc for Comparable wrote:It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.

All things are lawful, but not all things are profitable.

Campbell Ritchie

Marshal

Posts: 56570

172

posted 4 months ago

would in those circumstances print

The best explanation I can think of about ordering is in the Java™ Tutorials. Making a class implement Comparable implies that you are defining a

Now let's try adding them to a TreeSet. You have two cars doing 72mph, and only one of them will be added; if you add them in the order 1 2 3, you will add the two Fords and not the Mercedes. We now have the situation where the actual contents of the Set and how it would be displayed with

Remembering that compareTo should be anti‑symmetrical:

∀

You should always implement compareTo so it follows equals():-

∀

But implementing compareTo as

∀

You can combine equations 2 and 3:-

Or every time equals() returns

Had you not overridden equals() in that car class, this is what would have happened:The errors are getting even better The order of printing in both HashSets might be different from that shown above.

The equals() method returnsKnute Snortum wrote:. . . recommended . . . that natural orderings be consistent with equals. . . .

`true`whenever two Objects are compared which are equivalent to each other by the definition you are applying to your class. So

`System.out.println(myObject.equals(yourObject));`

would in those circumstances print

`true`.

The best explanation I can think of about ordering is in the Java™ Tutorials. Making a class implement Comparable implies that you are defining a

__total ordering__, and you are saying:-

It would in theory be possible to have an ordering without overriding the equals() method, but let's see what happens if you both implement Comparable and override equals(); you normally would do both together. Let's have a Car class where equals() takesFor every two instances of that class,x₁ andx₂, we can always say that one of the following three statements is true:-1: x₁ is greater thanx₂2: x₁ is less thanx₂3: x₁ is the same ranking asx₂

`make`and

`registrationNumber`into consideration, and we then compare them by speed. So you have two cars whose toString methods return:-

Now we have the barmy situation where1=Ford, NV16 XNP 66mph

2=Ford, NV16 XNP 72mph

`System.out.println(`displays

*car*₁.equals(*car*₂));`true`but your compareTo method tells you that

*car*₁ is less than

*car*₂. How daft! If you are going to return

`true`from equals() you really ought to be returning 0 from compareTo. Now, let's imagine a third Car, whose toString method returns

Let's imagine that whoever wrote that class recovered competence long enough to remember to override hashCode() and did it correctly. Now let's add those three Car objects to a HashSet. The two Fords will be regarded as equal to each other using equals and hashCode, so only the first Ford will be added to the Set and the Set will contain one Ford and one Mercedes.3=Mercedes, NA15 YFC 72mph

Now let's try adding them to a TreeSet. You have two cars doing 72mph, and only one of them will be added; if you add them in the order 1 2 3, you will add the two Fords and not the Mercedes. We now have the situation where the actual contents of the Set and how it would be displayed with

`System.out.println(mySet);`differs by the order of addition, and the contents of different Set implementations differs from each other.That is why happens if you implement compareTo wrongly; the second example shows a TreeSet going wrong because the implementation is here

__not consistent with equals__.

Remembering that compareTo should be anti‑symmetrical:

∀

*x*,

*y*•

*x*.compareTo(

*y*) == 0 ⇒

*y*.compareTo(

*x*) == 0 (1)

You should always implement compareTo so it follows equals():-

∀

*x*,

*y*•

*x*.equals(

*y*) ⇒

*x*.compareTo(

*y*) == 0 (2)

But implementing compareTo as

__consistent with equals__means that equals() also follows compareTo():-

∀

*x*,

*y*•

*x*.compareTo(

*y*) == 0 ⇒

*x*.equals(

*y*) (3)

You can combine equations 2 and 3:-

__Consistency with equals__≙ ∀

*x*,

*y*•

*x*.equals(

*y*) ⇔

*x*.compareTo(

*y*) == 0

Or every time equals() returns

`true`, compareTo returns 0 and every time compareTo returns 0, equals returns

`true`. QED

Had you not overridden equals() in that car class, this is what would have happened:The errors are getting even better The order of printing in both HashSets might be different from that shown above.