-1

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?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 2
    Where did you get that citation from? What code have you tried to sort a 1d array? – luk2302 Aug 15 '20 at 12:31
  • Is that answer your question https://stackoverflow.com/questions/21966814/java-arrays-sort-method-takes-1d-arrays-but-i-can-pass-a-2d-array-as-well-the ? – Eklavya Aug 15 '20 at 12:33
  • It is possible to sort an `int[][]` in descending order because you basically compare `int[]`s against each others. And as per [JLS, §10](https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html) "*Arrays are objects*". – Turing85 Aug 15 '20 at 12:34
  • `The direct superclass of an array type is Object` so you can use objects in comparator where 2D array is 1D array of 1D array/object but for 1D array you need to pass primitive in comparator which is not valid – Eklavya Aug 15 '20 at 12:38
  • And if you are complaining about why there is no build-in method for sorting array descending order, then write your own sort function for that, or you can do using stream api in one line https://stackoverflow.com/a/56673782/4207306 – Eklavya Aug 15 '20 at 12:47

3 Answers3

2

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

Turing85
  • 18,217
  • 7
  • 33
  • 58
1

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
Joni
  • 108,737
  • 14
  • 143
  • 193
1

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]
  • 1
    `.mapToInt(i -> i)` can be replaced with `mapToInt(Integer::intValue)` =) – Turing85 Aug 15 '20 at 13:30
  • Depending on the reader, it may be more readable =) (stream-operations tend to favor method references over lambda expressions) – Turing85 Aug 15 '20 at 13:39
  • 1
    As an aside: I would mention that this approach has `O(n)` memory overhead since `n` `Integer`-objects and one additional `int[]` of length `n` are created. – Turing85 Aug 15 '20 at 13:46