views:

405

answers:

4

Hello!

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.

+14  A: 

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.

Michael Myers
I would tend to answer: it makes no sense ;)Thank you, I forgot that there's such thing as a Comparator ;)
ivan_ivanovich_ivanoff
Right question.
Joshua
+1  A: 

Effective Java recommends that if you don't implement compareTo consistent with equals you should clearly indicate so:

The recommended language is "Note: This class has a natural ordering that is inconsistent with equals."

Fabian Steeg
A: 

Just put this code in the equals method and dont ever think about it again:

public boolean equals(Object obj) {
 if (this == obj) return true;
 if (!(obj instanceof MyClass)) return false;
 return 0 == this.compareTo((MyClass) obj);
}
Azder
But if you implement equals(), you must implement hashcode() also. Otherwise strange things can happen.
Michael Myers
You can delegate hashCode to some other property or a method that returns a comparable int value. But dont bother, since hashCode is like checking if its a same reference, not if they have same value.
Azder
+3  A: 

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.

Laplie