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

2022-09-02 23:19:50
int[] arr2 = new int[] {54, 432, 53, 21, 43};

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

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

这也给出了一个错误。

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

答案 1

您可以将类型的输入排序为: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);

答案 2

鉴于

int[] array = ... ;

要按升序排序,只需执行

Arrays.sort(array);

以下是排序降序的漂亮方法:

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

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

这可以通过在排序之前和之后对int值进行按位补足来工作。这提供了每个可能的int值的排序的精确,无损的反转。要看到这一点,你必须明白Java ints使用二的补码表示。考虑一下 ints 是否只有三位。所有值将如下所示:

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

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

请注意,这与否定不同,否定在这里没有做正确的事情。它反映了零的表,因此零的否定为零,-1的否定为1,依此类推。这是不对称的,因为MIN_VALUE的否定是MIN_VALUE。因此,使用否定来尝试执行降序排序是行不通的。-

最后,装箱和使用比较器是有效的,但它要慢得多,并且它为(几乎)每个int值分配一个单独的对象。我建议避免拳击。