Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort integer array in ascending and descending order using lambda only in java

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);
like image 603
WhiteWalker Avatar asked Jan 10 '19 10:01

WhiteWalker


Video Answer


3 Answers

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);
like image 191
Naman Avatar answered Oct 10 '22 15:10

Naman


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.

like image 12
Stuart Marks Avatar answered Oct 10 '22 15:10

Stuart Marks


Sort in ascending order :

  1. int[] ascArr = Arrays.stream(arr2).boxed().sorted(Comparator.naturalOrder())
                                      .mapToInt(Integer::intValue).toArray();
    
  2. int[] ascArr = IntStream.of(arr2).boxed().sorted((a, b) -> Integer.compare(a, b))
                                     .mapToInt(Integer::intValue).toArray();
    
  3. int[] ascArr = Arrays.stream(arr2).sorted().toArray();


Sort in descending order :

  1. int[] descArr = Arrays.stream(arr2).boxed().sorted(Comparator.reverseOrder())
                                       .mapToInt(Integer::intValue).toArray();
    
  2. int[] descArr = IntStream.of(arr2).boxed().sorted((a, b) -> Integer.compare(b, a))
                                      .mapToInt(Integer::intValue).toArray();
    
like image 7
Nicholas Kurian Avatar answered Oct 10 '22 16:10

Nicholas Kurian