简体   繁体   中英

Comparator for sorting 2D arrays and 1D arrays in Java

I used the following code for sorting a 2D array of int[][] type in reverse order by making use of a comparator.

int[][] arr = {{2,3},{3,5},{5,8}};
      
      Arrays.sort(arr, (a,b) -> Integer.compare(b[1], a[1]));

But I am unable to sort a 1D array of int[] type using similar approach. On the internet I found information saying "The only way to sort a primitive array in descending order is, first sort the array in ascending order and then reverse the array in place."

Why am I able to sort a 2D array of primitive type, but not a 1D array using comparator?

It is possible to sort an int[][] in descending order because one basically compares int[] s against each others. As per JLS, §10 : " ... Arrays are objects... ".

Looking closer at the Arrays API, we find method sort(T[], Comparator<? super T>) , which, together with some static builder methods from Comparator , allows to reverse-sort an array of objects:

T[] someArray =  ...
Arrays.sort(someArray, Comparator.<T>naturalOrder().reversed())

Ideone Demo

This only works for object-arrays, not for primitive arrays. And for primitive arrays, we do not have any method sort(int[], Comparator<...>) in Arrays (probably because one cannot use primitives as generic types, project Valhalla may or may not change this in the future).

So yes, sorting an array of primitives and then reversing it seems like the only option if one wants to have constant memory overhead. It would look something like this (sketch):

final int[] values = { 1, 5, 3, 2, 4 };
Arrays.sort(values);
reverse(values);

Ideone Demo

You can use Stream to convert an int to an Integer , do sort using a Comparator and reconvert it to an int[] .

final int[] values = {2, 0, 5, 1, 3, 4};
int[] reversed = IntStream.of(values)
    .boxed()
    .sorted(Comparator.reverseOrder())
    .mapToInt(i -> i)
    .toArray();
System.out.println(Arrays.toString(reversed));

output:

[5, 4, 3, 2, 1, 0]

There just aren't any built-in sort methods that accept a 1D primitive array and a Comparator .

As for why , only the designers can say authoratively, but here are some arguments against having them:

  • Primitive arrays are not used very often in Java programs to begin with.
  • A sort implementation that uses Comparator would need to wrap every array element in an object to pass them to the Comparator anyway, so you might as well have the user convert the array of int into an array of Integer themselves.
  • You would need to add 7 or 14 more Arrays.sort implementations which is a non-trivial amount of code to test
  • The most common use case for a custom comparator is sorting in reverse, and you can already achieve that by first sorting and then reversing

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