Search code examples
javagenericscomparable

Trouble Understanding Comparable<T> cast


I just wrote a method that takes two arguments: 1. An array list of any type that extends Number, and 2. a number of the same type. This method should return an array list of all numbers less than the second argument.

My class is called Quiz3FinalQuestion<T extends Comparable>>

My method I wrote looks like this,

public static <T extends Number> ArrayList<T> lessThan(ArrayList<T> lst, T number) {
        ArrayList<T> arLst = new ArrayList<>();
        for (T obj: lst) {
            if (((Comparable<T>) obj).compareTo(number) < 0)
                arLst.add(obj);
        }
        return arLst;
}

It works as expected, but if I didn't have the Java pre-compiler telling me to cast obj to type Comparable, this wouldn't have run. I'm assuming that the number parameter gets cast in the Comparable version of compareTo. So when I add an obj to my arLst, the object should get cast back into type T, right? Also, are there any simpler ways to compare wrapper class objects of unknown type T?


Solution

  • You can enforce that T also extends Comparable<? super T>:1

    public static <T extends Number & Comparable<? super T>>
    ArrayList<T> lessThan(ArrayList<T> lst, T number) {
        ...
    }
    

    Then you can remove the cast.


    1. See e.g. Explanation of generic <T extends Comparable<? super T>> in collection.sort/ comparable code? for why we don't just use Comparable<T>.