0
public class ClassX<T> implements Comparable<ClassX<T>> {

   private T o;

   public ClassX(T o) {
       this.o = o;
   }

   public T getObject() {
       return o;
   }

   public void setObject(T o) {
       this.o = o;
   }

   @Override
   public int compareTo(ClassX<T> arg0) {
       return o.compareTo(arg0.o);
   }
}

If I have a class like this and I want to implement the Comparable interface, I read that I have to change ClassX<T> to ClassX<T extends Comparable<T>>. But what if I also want to use my ClassX for objects that don't implement the Comparable interface, knowing that I would not be able to use the method compareTo() for those objects?

19
  • "what if I also want to use my ClassX for objects that don't implement the Comparable interface" - Then you will be basically in violation of the Comparable interface contract. Commented Nov 7, 2020 at 2:38
  • 1
    So you want something like "conditional implementation of Comparable"? That is, ClassX<T> will implement Comparable if and only if T implements Comparable? Did I understand correctly? Commented Nov 7, 2020 at 2:38
  • 1
    One (ugly) way to do this is to try to cast T to Comparable, and if it fails, throw a UnsupportedOperationException. Conditional implementation does not exist in Java. Commented Nov 7, 2020 at 2:52
  • 1
    @hfontanez Well, something similar to that happens when you try to sort a Stream of non-Comparable objects. If Stream uses this approach, I'd say it's fine to use it in our code too, albeit ugly. Commented Nov 7, 2020 at 2:57
  • 1
    OP, now that you said you are making a Pair class, I suggest not doing that. Write more specific classes instead. They are more future-proof, among other things. Commented Nov 7, 2020 at 3:01

2 Answers 2

1

Another option is, instead of implementing Comparable, have a static method that returns a Comparator, and this method can only be called when the constraint on T is met. So then your ClassX can be used with T that do not implement Comparable, but you can only obtain Comparators for ClassXs with T that do implement Comparable.

public class ClassX<T> {
    private T o;

    // ...

    public static <T extends Comparable<? super T>> Comparator<ClassX<T>> getComparator() {
        return (x, y) -> x.o.compareTo(y.o);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

How about creating another layer of hierarchy to support this:

public class NonComparableClassX<T> implements Comparable<NonComparableClassX<T>> {
 // ....

  @Override
   public int compareTo(ClassX<T> arg0) {
     // throw Exception;
   }
}

public class ClassX<T> extends NonComparableClassX<T> {
 // ....

  @Override
   public int compareTo(ClassX<T> arg0) {
     // Implement comparables here
   }
}

This way you can encapsulate all objects as ClassX, which can also be of the type NonComparableClassX if need be

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.