Search code examples
javacomparator

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>.


Solution

  • 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.