I have a user-defined class that is supposed to be generic to accept Integers, Floats, Doubles, etc. but also needs to be able to be compared. It looks like:
public class MyClass<T extends Comparable<T>> implements Comparable<MyClass<T>>{
private T myClassObject;
...
And the compareTo method looks like
@Override
public int compareTo(MyClass<T> o){
return this.myClassObject.compareTo((T) o));
}
Now in a later class that is supposed to be creating an ArrayList of MyClass objects and comparing them, I get:
sort(java.util.List<T>)' in 'java.util.Collections' cannot be applied to '(java.util.ArrayList<MyClass<?>>)
The ArrayList that holds these MyClass objects looks like:
ArrayList<MyClass<?>> temp = new ArrayList<MyClass<?>>();
Is it failing because of the wildcard generic use? Do I need to specify that ? extends Number or something else?
The T
in the List<T>
parameter in the generic Collections.sort
method, enforces that you pass in a list with elements that can be compared with each other.
A List<MyClass<?>>
can have elements that are not comparable with each other.
With a List<MyClass<?>>
, you can potentially put a MyClass<String>
and a MyClass<Integer>
into the same list!
ArrayList<MyClass<?>> temp = new ArrayList<MyClass<?>>();
temp.add(new MyClass<>(1));
temp.add(new MyClass<>("String"));
To sort this list, Collections.sort
would have to know how to compare a MyClass<Integer>
with a MyClass<String>
! And that's nonsense. More importantly, Comparable<T>
doesn't support this operation.
List.sort
- a non-generic method - on the other hand, doesn't have this "equality constraint", and does a bunch of unsafe casts, and will throw an exception at runtime if you try to sort a list with different kinds of MyClass
.
Though unrelated to the error, note that you implemented Comparable
wrongly. It should be:
return myClassObject.compareTo(o.myClassObject);