Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does it make sense for equals and compareTo to be inconsistent?

I want to make a class usable in SortedSet | SortedMap.

class MyClass implements Comparable<MyClass>{
  // the only thing relevant to comparisons:
  private final String name;

  //...
}

The class' instances must be sorted by their name property.
However, I don't want equally named instances to be considered as equal.

So a SortedSet content would look like a, a, a, b, c.
(Normally, SortedSet would only allow a, b, c)

First of all: is this (philosophically) consistent?

If so, do I have to expect unpredictable behavior, when I don't override equals(...) and hashCode()?

Edit:
I am sorry, my question seems inconsistent:
I want to put multiple "equal" values inside a set, which doesn't allow this by concept.
So, please don't reply to my question anymore.
Thanks to all who already replied.

like image 504
ivan_ivanovich_ivanoff Avatar asked Apr 27 '09 19:04

ivan_ivanovich_ivanoff


People also ask

What happens if equals () is not consistent with compareTo () method?

But if compareTo() is "inconsistent with equals" then this code can throw the exception, because a. compareTo(b) can return zero when a. equals(b) is false.

Why bother with equals () Why not just use compareTo () throughout?

Equals can be more efficient then compareTo. If the length of the character sequences in String doesn't match there is no way the Strings are equal so rejection can be much faster. Moreover if it is same object (identity equality rather then logical equality), it will also be more efficient.

What is the difference between equals () and compareTo () function?

The equals() tells the equality of two strings whereas the compareTo() method tell how strings are compared lexicographically.

Will two object always be equal when their compareTo () method returns zero?

It is recommended that compareTo only returns 0 , if a call to equals on the same objects would return true : The natural ordering for a class C is said to be consistent with equals if and only if e1. compareTo(e2) == 0 has the same boolean value as e1. equals(e2) for every e1 and e2 of class C.


2 Answers

Let me ask you a question: does it make sense to have a.compareTo(b) return 0 and a.equals(b) return false?

I would use a Comparator<MyClass> instead. This is why all SortedMap/SortedSet implementations that I know of allow you to pass in a Comparator at creation.

like image 84
Michael Myers Avatar answered Oct 05 '22 17:10

Michael Myers


From the Javadoc for Comparable

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

If you want to have compareTo inconsistent with equals(), it is recommended that you instead use an explicit comparator by providing a class that implements Comparator.

If so, do I have to expect unpredictable behavior, when I don't override equals(...) and hashcode()?

You should still override equals() and hashcode(). Whether or not equals() and hashcode() are consistent with compareTo is a different matter.

like image 24
Laplie Anderson Avatar answered Oct 05 '22 16:10

Laplie Anderson