Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there ever a reason to implement java.util.Comparable for a type other than itself? [closed]

Tags:

java

Classes implementing Comparable<T> typically implement it for themselves, e.g.

class MyInteger implements Comparable<MyInteger> { ... }
class MyString implements Comparable<MyString> { ... }

But there's nothing to stop you implementing it for a different type:

class MyString implements Comparable<MyInteger> { ... }

which would allow you to compare a MyString to a MyInteger.

As is described in the Javadoc, Comparable is intended to model the natural ordering, which is a total order, and so to be able to have anti-symmetry, the type of the argument of compareTo should be the same as the type on which that method is defined.

But are there any practical uses (abuses) of implementing class SomeType implements Comparable<OtherType>?


Update: The answers that Joni and I have provided give practical examples of where Comparable<Supertype> are implemented implicitly, i.e. where your classes implement that interface transitively. It would be interesting to know if anybody has an example where it might be used explicitly.

like image 285
Andy Turner Avatar asked Jan 20 '17 09:01

Andy Turner


People also ask

Why do we implement comparable in Java?

The Comparable interface is used to compare an object of the same class with an instance of that class, it provides ordering of data for objects of the user-defined class.

What are the benefits of implementing the Comparable interface?

The benefit of implementing the interface is that some methods specifically require object that implements the Comparable interface. It gives them a guarantee that the object you're passing has a compareTo method with the correct signature.

Why would a class implement the comparable interface What is the method of the Comparable interface?

The Comparable interface defines the compareTo method used to compare objects. If a class implements the Comparable interface, objects created from that class can be sorted using Java's sorting algorithms.

Do you need to implement comparable to use compareTo?

When you implement Comparable interface, you need to implement method compareTo() . You need it to compare objects, in order to use, for example, sorting method of ArrayList class.


2 Answers

If there is a parent/child relationship you do find this. For example, the Enum class implements Comparable<E> with E being a type parameter. All enums share this one compareTo implementation.

To clarify: Enum<ConcreteClass> implements Comparable<ConcreteClass>. If it followed the pattern you'd expect it to implement Comparable<Enum<ConcreteClass>>

like image 118
Joni Avatar answered Sep 20 '22 00:09

Joni


The obvious (in hindsight) case where you encounter this is in subclasses of classes implementing Comparable:

abstract class Superclass implements Comparable<Superclass> {}
abstract class Subclass extends Superclass {}

System.out.println(Subclass.class.getGenericInterfaces()[0]);
// Prints Comparable<Superclass>

As ever, there is a great insight in Bloch's Effective Java 2nd Ed, in Item 8 "Consider implementing Comparable":

One consequence of these three provisions [of the compareTo contract] is that the equality test imposed by a compareTo method must obey the same restrictions imposed by the equals contract: reflexivity, symmetry, and transitivity. Therefore the same caveat applies: there is no way to extend an instantiable class with a new value component while preserving the compareTo contract, unless you are willing to forgo the benefits of object-oriented abstraction (Item 8).

So, what this says is that provided your subclass doesn't have any more values than the superclass used to determine ordering, implementing Comparable<Supertype> is reasonable.

The implication of this, in addition to the general requirements of the Comparable, is that Comparable<Superclass> should be implemented identically in Superclass and all subclasses.

That suggests that compareTo should be marked final, if Superclass is a class. If it's an interface, you could provide a default implementation in Java 8+; but there's no (in-built) way to enforce that the method is not overridden differently in implementing classes.

like image 43
Andy Turner Avatar answered Sep 18 '22 00:09

Andy Turner