如何仅在Java中使用Lambda以升序和降序对整数数组进行排序

时间:2019-01-10 10:45:04

标签: java arrays lambda java-8 java-stream

int[] arr2 = new int[] {54, 432, 53, 21, 43};

我正在使用它进行排序,但是它给出了一个错误。

Arrays.sort(arr2, (a, b) -> a - b);

这也给出了错误。

arr2.sort((a, b) -> a - b);

6 个答案:

答案 0 :(得分:9)

您可以将Integer[]类型的输入排序为:

Integer[] arr2 = new Integer[] {54,432,53,21,43};
Arrays.sort(arr2, Comparator.reverseOrder());

或可能具有以下原始类型:

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();

或进一步使用现有答案之一中的技巧(请注意,应谨慎使用边界值):

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();

编辑 :对于就地升序排序,您只需要执行:

int[] arr2 = new int[]{54, 432, 53, 21, 43};
Arrays.sort(arr2);

答案 1 :(得分:9)

给予

int[] array = ... ;

要升序排序,只需执行

Arrays.sort(array);

这是一种降序排序的好方法:

Arrays.setAll(array, i -> ~array[i]);
Arrays.sort(array);
Arrays.setAll(array, i -> ~array[i]);

这比升序排序然后反转数组要慢一点;它必须对数组进行额外的传递。运行时由对任何有效大小的数组的排序控制,因此不太可能引起注意。

这可以通过对排序前后的int值进行按位补码来实现。这样就可以精确无损地反转每个可能的int值的顺序。要了解这一点,您必须了解Java int使用two's complement表示形式。考虑int是否只有三位。所有值如下:

         100  101  110  111  000  001  010  011
          -4   -3   -2   -1   0    1    2    3
MIN_VALUE ^

按位补数运算符~将每一位取反。通过检查,您可以看到这反映了表在-1和0之间的枢轴点,因此-4变为3,-3变为2,依此类推。此外,另一个补码将恢复原始值。因此,补值的升序是原始值的降序。

请注意,这与否定-不同,否定dateLbl.center = CGPoint(x: self.scrollView.center.x, y: self.scrollView.center.y + 100)在这里没有做正确的事情。它反映了表 at 处为零,因此零的取反为零,-1的取反为1,依此类推。这是不对称的,因为MIN_VALUE的取反为MIN_VALUE。因此,使用否定尝试执行降序排序是行不通的。

最后,装箱和使用Comparator可以工作,但速度慢得多,并且它为(几乎)每个int值分配了一个单独的对象。我建议避免拳击。

答案 2 :(得分:5)

升序排列:

  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();


降序排列:

  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();
    

答案 3 :(得分:3)

有其他方法可以使用流从未排序的流中创建int的排序数组,如其他答案所示。这些方法的缺点是要么需要装箱/拆箱(以便可以使用Comparator<Integer>),要么需要新的数组来容纳元素。

这是一种无需装箱/拆箱就地排序的方法。首先,按升序:

int[] arr2 = ...
Arrays.sort(arr2);

不幸的是,无法使用单行操作按降序对就地排序。您需要先升序排序,然后反转数组:

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;
}

编辑:正如@Holger在评论中指出的那样,上述for循环可以如下进行改进:

for (int left = 0, right = arr2.length - 1; left < right; left++, right--) {
    int temp = arr2[right];
    arr2[right] = arr2[left];
    arr2[left] = temp;
}

另一种方法是按升序排序,然后将元素以相反的顺序放置到新数组中:

int[] arr2 = ...
Arrays.sort(arr2);

int size = arr2.length;
int[] reversed = new int[size];
Arrays.setAll(reversed, i -> arr2[size - i - 1]);

这使用Arrays.setAll完成任务。

答案 4 :(得分:2)

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+", ");
        }
    }

}
  

输出

     

降序排列:

     

432,54,53,43,21,

     

升序:

     

21、43、53、54、432,

编辑:按照自然顺序(IntStream.of(arr2) .sorted() .toArray())

进行排序要简单得多

感谢Holger

答案 5 :(得分:2)

如果您明确需要自定义比较器lambda,请尝试以下操作:

    int[] arr2 = new int[] {54,432,53,21,43};
    int[] arr3 = IntStream.of(arr2).boxed().sorted((a, b) -> a - b).mapToInt(Integer::intValue).toArray();