Skip to content

Can’t pass wildcard Comparator to function

I have the following sort method in a clone of ArrayList:

@SuppressWarnings({"rawtypes", "unchecked"})
public void sort(Comparator<? super E> c){
    if(c == null){
        // Use ascending order (only works if types are comparable)
        class ascComparator<T> implements Comparator<T> {
            public int compare(T a, T b) {
                // This will raise an exception if the types are not comparable
                return ((Comparable)a).compareTo(b);
            }
        }
        c = new ascComparator<E>();
    }
    // Cast the internal array to comparable then call merge sort
    sorter.mergeSort((Comparable[])array, c);
}

The sorter object is an instance of Sort:

public class Sort {
    @SuppressWarnings("unchecked")
    public <E extends Comparable<E>> E[] mergeSort(E[] list, Comparator<? super E> c){
        ...
    }
}

I get the following error on the sorter.mergeSort line:

The method mergeSort(E[], Comparator<? super E>) in the type Sort is not applicable for the arguments (Comparable[], Comparator<capture#8-of ? super E>)

I’m not sure why this is happening as both the parameter and argument have type Comparator<? super E>.

Answer

Thanks to everyone for their comments. I’ve now fixed it.

@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c){
    if(c == null){
        // Use ascending order (only works if types are comparable)
        class ascComparator<T> implements Comparator<T> {
            public int compare(T a, T b) {
                // This will raise an exception if the types are not comparable
                return ((Comparable<T>)a).compareTo(b);
            }
        }
        c = new ascComparator<E>();
    }
    // Cast the internal array to E then call merge sort
    sorter.sort((E[]) array, c);
}

As Kayaman said, I shouldn’t use rawtypes so I’ve given ascComparator parameter T. I’ve also casted array to E instead of Comparable as it didn’t do what I thought it did. I’ve also changed Sort:

@SuppressWarnings("unchecked")
private <E> E[] mergeSort(E[] list, Comparator<E> c){
    ...
}

As pointed out by Louis Wasserman I don’t need the Comparable type cast.