int[] arr2 = new int[] {54, 432, 53, 21, 43};
I am using this to sort but it is giving an error.
Arrays.sort(arr2, (a, b) -> a - b);
This is also giving an error.
arr2.sort((a, b) -> a - b);
You could sort the input of type Integer[] as :
Integer[] arr2 = new Integer[] {54,432,53,21,43};
Arrays.sort(arr2, Comparator.reverseOrder());
or possibly with primitive types as :
int[] arr2 = new int[]{54, 432, 53, 21, 43};
int[] sortedArray = Arrays.stream(arr2)
.boxed()
.sorted(Comparator.reverseOrder()) // just use 'sorted()' for ascending order
.mapToInt(Integer::intValue)
.toArray();
or further using a trick from one of the existing answers (do note that it should be cautiously used with boundary values though) :
int[] sortedArray = Arrays.stream(arr2)
.map(i -> -i).sorted().map(i -> -i) // just use 'sorted()' for ascending order
// Edit - use map(i -> ~i).sorted().map(i -> ~i) to be safe from the issue with Integer.MIN_VALUE
.toArray();
Edit: For an in-place ascending order sort, you just need to perform :
int[] arr2 = new int[]{54, 432, 53, 21, 43};
Arrays.sort(arr2);
Arrays.stream(arr2).sorted().toArray() or just sort in-place with Arrays.sort(arr2). However, be aware that the trick with negating the values does not work if one or more occurrences of Integer.MIN_VALUE are among the values.map.sort.map solution about boundary values.~) instead of minus (-) would solve the issue with Integer.MIN_VALUE.Given
int[] array = ... ;
To sort ascending, simply do
Arrays.sort(array);
Here's a pretty way to sort descending:
Arrays.setAll(array, i -> ~array[i]);
Arrays.sort(array);
Arrays.setAll(array, i -> ~array[i]);
This is a tiny bit slower than sorting ascending and then reversing the array; it has to do an extra pass over the array. The runtime is dominated by the sorting for an array of any significant size, so it's unlikely to be noticeable.
This works by doing a bitwise complement of the int values before and after the sort. This provides an exact, lossless reversal of the ordering of every possible int value. To see this, you have to understand that Java ints use two's complement representation. Consider if ints were to have only three bits. All the values would be as follows:
100 101 110 111 000 001 010 011
-4 -3 -2 -1 0 1 2 3
MIN_VALUE ^
The bitwise complement operator ~ inverts every bit. You can see by inspection that this reflects the table about a pivot point between -1 and 0, so -4 becomes 3, -3 becomes 2, etc. Also, another complement will restore the original value. Thus, an ascending sort on the complemented values is a descending sort on the original values.
Note that this differs from negation - which doesn't do the right thing here. It reflects the table at zero, so the negation of zero is zero, the negation of -1 is 1, etc. This is asymmetric, because the negation of MIN_VALUE is MIN_VALUE. Thus, using negation in an attempt to perform a descending sort doesn't work.
Finally, boxing and using a Comparator works, but it's considerably slower, and it allocates a separate object for (almost) every int value. I recommend avoiding boxing.
Sort in ascending order :
int[] ascArr = Arrays.stream(arr2).boxed().sorted(Comparator.naturalOrder())
.mapToInt(Integer::intValue).toArray();
int[] ascArr = IntStream.of(arr2).boxed().sorted((a, b) -> Integer.compare(a, b))
.mapToInt(Integer::intValue).toArray();
int[] ascArr = Arrays.stream(arr2).sorted().toArray();
Sort in descending order :
int[] descArr = Arrays.stream(arr2).boxed().sorted(Comparator.reverseOrder())
.mapToInt(Integer::intValue).toArray();
int[] descArr = IntStream.of(arr2).boxed().sorted((a, b) -> Integer.compare(b, a))
.mapToInt(Integer::intValue).toArray();
There are different ways to create a sorted array of ints out of an unsorted one using streams, as the other answers show. These approaches have the disadvantage of either requiring boxing/unboxing (so that a Comparator<Integer> can be used), or that new arrays are needed to accommodate the elements.
Here's a way to sort in-place without boxing/unboxing. First, in ascending order:
int[] arr2 = ...
Arrays.sort(arr2);
Unfortunately, there's no way to sort in-place in descending order using a single-line operation. You will need to sort ascending first, then reverse the array:
int[] arr2 = ...
Arrays.sort(arr2);
int size = arr2.length;
for (int left = 0; left < size / 2; left++) {
int right = size - i - 1;
int temp = arr2[right];
arr2[right] = arr2[left];
arr2[left] = temp;
}
EDIT: As @Holger points out in the comments, the for loop above could be improved as follows:
for (int left = 0, right = arr2.length - 1; left < right; left++, right--) {
int temp = arr2[right];
arr2[right] = arr2[left];
arr2[left] = temp;
}
An alternative is to sort in ascending order and then place the elements in reverse order into a new array:
int[] arr2 = ...
Arrays.sort(arr2);
int size = arr2.length;
int[] reversed = new int[size];
Arrays.setAll(reversed, i -> arr2[size - i - 1]);
This uses Arrays.setAll to accomplish the task.
for(int left = 0, right = arr2.length-1; left < right; left++, right--) … which may also be more efficient in some cases.public class lambdaTest {
public static void main(String[] args) {
int[] arr2 = new int[] {54,432,53,21,43};
int[] sorted = IntStream.of(arr2)
.boxed()
.sorted(Comparator.reverseOrder())
.mapToInt(i -> i)
.toArray();
System.out.println("In decending Order:");
for(int ss : sorted)
{
System.out.print(ss+", ");
}
System.out.println();
int[] reversed = IntStream.range(0, sorted.length)
.map(i -> sorted[sorted.length-i-1])
.toArray();
System.out.println("In Ascending Order: ");
for(int ss1 : reversed)
{
System.out.print(ss1+", ");
}
}
}
OUTPUT
In decending Order:
432, 54, 53, 43, 21,
In Ascending Order:
21, 43, 53, 54, 432,
Edit: much simpler to sort in natural order (IntStream.of(arr2) .sorted() .toArray())
Thanks to Holger
IntStream.of(arr2) .sorted() .toArray()) and reverse that, to get both, instead of sorting in reverse order and reverse that again.Comparator).int[] arr2 = new int[] {54, 432, 53, 21, 43};
int[] answer = Arrays.stream(arr2).boxed()
.sorted(Comparator.comparing(Integer::intValue).reversed())
.mapToInt(Integer::intValue)
.toArray()
(a,b)->a-bforintvalues. It may work in some use cases, but the difference between twointvalues may be bigger than theintvalue range and cause overflows. Therefore, use(a,b) -> Integer.compare(a, b)resp.Integer::compare. To reverse the order, use(a,b) -> Integer.compare(b, a). Do not negate the value returned by a compare function, that will fail if the value isInteger.MIN_VALUE.sortmethod and thesort(T[] a, Comparator<? super T> c)method does not support primitive type arrays.(a,b)->a-bwithInteger.MIN_VALUE.int[][] array, then,array instanceof Object[]will also betrue. So,int[][]being an array of objects, you can use the generic methodsort(T[] a, Comparator<? super T> c). But read this comment again, using minus as comparator works for some (small) values but is broken in general and will lead to hard-to-track bugs