如何在java中仅使用lambda按升序和降序对整数数组进行排序

Whi*_*ker 9 java arrays lambda java-8 java-stream

int[] arr2 = new int[] {54, 432, 53, 21, 43};
Run Code Online (Sandbox Code Playgroud)

我正在使用它来排序,但它给出了一个错误.

Arrays.sort(arr2, (a, b) -> a - b);
Run Code Online (Sandbox Code Playgroud)

这也是一个错误.

arr2.sort((a, b) -> a - b);
Run Code Online (Sandbox Code Playgroud)

Nam*_*man 9

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

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

或者可能与原始类型:

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();
Run Code Online (Sandbox Code Playgroud)

或者进一步使用其中一个现有答案的技巧(请注意尽管应该谨慎使用边界值):

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();
Run Code Online (Sandbox Code Playgroud)

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

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

  • 正如[Stuart Marks的回答](/sf/answers/3789767551/)中所解释的那样,使用二进制非(`~`)而不是减号(`-`)可以解决`Integer.MIN_VALUE的问题`. (3认同)
  • 对于升序,您可以使用 `Arrays.stream(arr2).sorted().toArray()` 或使用 `Arrays.sort(arr2)` 就地排序。但是,请注意,如果值中出现一次或多次“Integer.MIN_VALUE”,则否定值的技巧将不起作用。 (2认同)

Stu*_*rks 9

特定

int[] array = ... ;
Run Code Online (Sandbox Code Playgroud)

要升序排序,只需这样做

Arrays.sort(array);
Run Code Online (Sandbox Code Playgroud)

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

Arrays.setAll(array, i -> ~array[i]);
Arrays.sort(array);
Arrays.setAll(array, i -> ~array[i]);
Run Code Online (Sandbox Code Playgroud)

这比排序升序然后反转阵列要慢一点; 它必须对数组进行额外的传递.运行时主要是对任何大小的数组进行排序,因此它不太可能引人注意.

这通过在排序之前和之后对int值进行逐位补充来实现.这提供了对每个可能的int值的排序的精确,无损的反转.要看到这一点,您必须了解Java int使用两个补码表示.考虑一下int是否只有三位.所有值都如下:

         100  101  110  111  000  001  010  011
          -4   -3   -2   -1   0    1    2    3
MIN_VALUE ^
Run Code Online (Sandbox Code Playgroud)

按位补码运算符~反转每一位.您可以通过检查看到这反映了关于-1和0之间的轴心点的表格,因此-4变为3,-3变为2,等等.另外,另一个补码将恢复原始值.因此,对补充值的升序排序是对原始值的降序排序.

请注意,这不同于在-这里做得不对的否定.它反映了表在零,所以零否定为零,-1的否定是1,等等,这是不对称的,因为MIN_VALUE的否定是MIN_VALUE.因此,在尝试执行降序排序时使用否定不起作用.

最后,装箱和使用Comparator工作,但速度相当慢,并为(几乎)每个int值分配一个单独的对象.我建议避免拳击.

  • @FedericoPeraltaSchaffner很可能.添加一些原始数组操作可能很有用.这似乎是一个经常被问到的问题,而常见的答案(例如涉及拳击的那些)表现得相当糟糕. (3认同)
  • 嗨!您是否需要用钻头完成所有这些工作,是否意味着需要一种新方法?即Arrays.sortDescending (2认同)

Nic*_*s K 5

按升序排序:

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


按降序排序:

  1. int[] descArr = Arrays.stream(arr2).boxed().sorted(Comparator.reverseOrder())
                                       .mapToInt(Integer::intValue).toArray();
    
    Run Code Online (Sandbox Code Playgroud)
  2. int[] descArr = IntStream.of(arr2).boxed().sorted((a, b) -> Integer.compare(b, a))
                                      .mapToInt(Integer::intValue).toArray();
    
    Run Code Online (Sandbox Code Playgroud)