7

Surprisingly, it seems there was no simple, one-liner kind of solution in java to sort int array in descending order before java 8. For example, check this post. Now that we have java 8, is there an elegant, simple, one-liner way using java 8 features, such as stream and lambda expression, to sort an int array in descending order?

Edit
I am interested in a solution for int[], not Integer[].

Edit
I am interested in a solution that only uses JAVA SE library.

Community
  • 1
  • 1
JBT
  • 8,498
  • 18
  • 65
  • 104
  • 1
    Possible duplicate: [Sort arrays of primitive types in descending order](http://stackoverflow.com/questions/215271/sort-arrays-of-primitive-types-in-descending-order) – Pshemo Aug 03 '15 at 01:19
  • 1
    You can always use `Arrays.sort()` and then iterate the array in reverse order... – fps Aug 03 '15 at 17:10

2 Answers2

12

With guava you could simply write

Ints.asList(a).sort(Comparator.reverseOrder());

It may be not so efficient since it requires boxing int to Integer, but it is elegant one-liner.

You can also write something like

int[] sorted = IntStream.of(a)
        .boxed()
        .sorted(Comparator.reverseOrder())
        .mapToInt(i -> i)
        .toArray();

but this also suffers from boxing and it needs to create new array.

Anyway I doubt you will find nice solution in standard Java free of boxing since Comparator<T> can accept only objects. For now best way would be using Arrays.sort and reverse its order manually.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • 3
    In my [StreamEx](https://github.com/amaembo/streamex) library there's a [shortcut](http://amaembo.github.io/streamex/javadoc/javax/util/streamex/IntStreamEx.html#reverseSorted--) for this: `IntStreamEx.of(a).reverseSorted().toArray()` (which does the same boxing/unboxing internally). In JDK there's no ready algorithm to sort primitive array with custom comparator, so it's not possible to do this without intermediate boxing (or some third-party library which implements such primitive sorting). – Tagir Valeev Aug 03 '15 at 05:34
4
int[] arr = ...;
Arrays.sort(arr);
int[] reversed = IntStream.range(0, arr.length)
                          .map(i -> arr[arr.length-i-1])
                          .toArray();

is probably the closest you could do if you don't want to box the int into its respective wrapper class for each value in the array.

If you suffer from performances by doing the sort once (O(nlogn)) and the reverse operation after (O(n)), you might want to look into Arrays.parallelSort and parallelize the IntStream.

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • or `IntStream.range(0, arr.length/2).forEach(i -> {int tmp = arr[i]; arr[i] = arr[arr.length-i-1]; arr[arr.length-i-1] = tmp;});` if you want to reverse in place in `arr` directly. – Alexis C. Aug 03 '15 at 22:14