简体   繁体   中英

Getting Compile time error while sorting arrays using generics in java

Here's my code:

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

public class SortingUsingGenerics {

    public static void main(String[] args) {
        Integer[] intArray = {1,5,4,2,10};
        String[] stringArray = {"Ä","X","C","B","M"};
        Float[] floatArray = {1.5f,2.8f,0.5f,10.3f,9.5f};

        // Sort and Print
        printArray(sortArray(intArray));
        printArray(sortArray(stringArray));
        printArray(sortArray(floatArray));

    }

    private static <MyArray> void printArray(MyArray[] inputArray) {
        for (MyArray element : inputArray) {
            System.out.print(element);
        }
        System.out.println();
    }

    public static <E> E[] sortArray(E[] inputArray){

        if (inputArray instanceof Integer[]){
            Collections.sort(Arrays.asList(inputArray),new Comparator<Integer>() {
                        public int compare(Integer o1, Integer o2) {
                            if (o1 == o2) {
                                return 0;
                            } else if (o1 > 02) {
                                return 1;
                            } else {
                                return -1;
                            }
                        }

                    });
        }
        return inputArray;
    }
}

The error I am getting is:

The method sort(List<T>, Comparator<? super T>) in the type Collections is not applicable for the arguments (List<E>, new Comparator<Integer>(){})

Could you please explain what I'm doing wrong here?

Your instanceof check doesn't really tell the compiler that inputArray is an Integer[] - the compile-time type is still just E[] .

However, you can cast perfectly easily, at which point it will work:

if (inputArray instanceof Integer[]) {
    Integer[] integers = (Integer[]) inputArray;
    Collections.sort(Arrays.asList(integers), ...);
}

Or even just:

if (inputArray instanceof Integer[]) {
    Collections.sort(Arrays.asList((Integer[]) inputArray), ...);
}

However, when you have a generic method and then do specific things for specific types, you should at least consider whether you really want a generic method after all.

In this scenario, there's not much value in deciding what to do based on if the array is an Integer[] , a Float[] , or a String[] - all of them implement the Comparable interface. Since the method doesn't allow for it, it doesn't make sense to sort anything that isn't Comparable either - we don't allow for the passing of a custom Comparator which would address this issue.

In that scenario, what would be most ideal is if you relied on the natural behavior of Comparable instead of your hand-written comparison method.

public static <E extends Comparable<E>> E[] sortArray(E[] inputArray){
    Collections.sort(Arrays.asList(inputArray), new Comparator<E>() {
        @Override
        public int compare(E o1, E o2) {
            return o1.compareTo(o2);
        }

    });
    return inputArray;
}

This approach ensures that whatever E you pass in that it's also a Comparable , so you can simply delegate to each object's compareTo method, while preserving the required type bound on the anonymous Comparator .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM