1

So I am trying to make a general utility function for sorting Lists of various types (mostly built-in wrappers, and Strings). The sample code is below:

public void sortArrays(List<?>... arr) {
    // do here
}

And it may be used as follows

List<Integer> a = // initialization
List<String> b = // initialization
...

sortArrays(a, b)

The function will sort varargs List and I'm planning to use Collections.sort(...) but unfortunately, it does not work on List of capture ofs. Is there a proper workaround or approach to what I'm trying to achieve?

ReiSchneider
  • 185
  • 1
  • 12

2 Answers2

2

The documentation of Collections#sort states that it accepts a List<T> as a parameter, where T is defined as:

<T extends Comparable<? super T>>

Therefore, you should be able to define a similar generic type in your sortArrays method:

public <T extends Comparable<? super T>> void sortArrays(List<T>... arr) {
    for (List<T> list : arr) {
        Collections.sort(list);
    }
}

This solution will work if your goal is to pass in lists of a single type. For passing lists of different types, see below.


There exists a hacky solution that utilizes raw types, allowing you to pass lists of different types to your sortArrays to method:

public static void main(String[] args) {
    List<Integer> integerList = new ArrayList<>(List.of(3, 2, 1));
    List<String> stringList = new ArrayList<>(List.of("6", "5", "4"));

    sortArrays(integerList, stringList);

    System.out.println(integerList);
    System.out.println(stringList);
}

public static void sortArrays(List<? extends Comparable>... arr) {
    for (List<? extends Comparable> list : arr) {
        Collections.sort(list);
    }
}

The output of the above snippet is:

[1, 2, 3]
[4, 5, 6]
Jacob G.
  • 28,856
  • 5
  • 62
  • 116
  • This will work if the varags list I am going to sort is of the same component type, but what I am trying to achieve is a general, all-purpose utility that can sort varargs list of different types – ReiSchneider Apr 15 '20 at 02:49
  • @ReiSchneider Thanks for the clarification; I'll see if I can come up with a solution that fits your use-case. – Jacob G. Apr 15 '20 at 02:51
1

Assuming you want each list to be independently sorted by their natural ordering, you can do this by using raw generics, however that is not recommended.

@SafeVarargs
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void sortArrays(List<? extends Comparable>... lists) {
    for (List<? extends Comparable> list : lists)
        Collections.sort(list);
}
List<Integer> a = Arrays.asList();
List<String> b = Arrays.asList();
List<Object> c = Arrays.asList();
sortArrays(a, b);
sortArrays(c); // compilation error because Object is not a Comparable
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Somehow, this works but it doesn't look neat with all the warnings suppressed. I guess there is no other approach than to do this. Thank you – ReiSchneider Apr 15 '20 at 03:17
  • @ReiSchneider Solution is to not do this, i.e. to simply call `sort()` for each list: `a.sort(null); b.sort(null);` – Andreas Apr 15 '20 at 03:21