用于在 Java 中对二维数组和一维数组进行排序的比较器

Comparator for sorting 2D arrays and 1D arrays in Java

我使用以下代码对 int[][] 类型的二维数组进行排序 逆序 通过使用比较器。

int[][] arr = {{2,3},{3,5},{5,8}};
      
      Arrays.sort(arr, (a,b) -> Integer.compare(b[1], a[1]));

但是我无法使用类似的方法对 int[] 类型的一维数组进行排序。在互联网上我发现信息说“按降序对原始数组进行排序的唯一方法是,先按升序对数组进行排序,然后再原地反转数组。”

为什么我可以对基本类型的二维数组进行排序,但不能使用比较器对一维数组进行排序?

只是没有任何 built-in 接受一维原始数组和 Comparator 的排序方法。

至于为什么,只有设计者可以权威地说,这里有一些反对意见:

  • 最初在 Java 程序中并不经常使用原始数组。
  • 使用 Comparatorsort 实现需要将每个数组元素包装在一个对象中以将它们传递给 Comparator,因此您不妨让用户转换将 int 的数组转换为 Integer 本身的数组。
  • 您需要再添加 7 或 14 个 Arrays.sort implementations,这是一个 non-trivial 的代码量来测试
  • 自定义比较器最常见的用例是反向排序,您已经可以通过先排序然后反向来实现

可以按降序对 int[][] 进行排序,因为基本上是将 int[] 相互比较。根据 JLS, §10:“...数组是对象...”。

仔细观察 Arrays API, we find method sort(T[], Comparator<? super T>), which, together with some static builder methods from Comparator,允许 reverse-sort 对象数组:

T[] someArray =  ...
Arrays.sort(someArray, Comparator.<T>naturalOrder().reversed())

Ideone Demo

这仅适用于 object-arrays,不适用于原始数组。对于原始数组,我们在 Arrays 中没有任何方法 sort(int[], Comparator<...>) (可能是因为不能将原始数组用作泛型类型,project Valhalla 将来可能会或可能不会更改)。

所以是的,如果想要拥有恒定的内存开销,那么对基元数组进行排序然后将其反转似乎是唯一的选择。它看起来像这样(草图):

final int[] values = { 1, 5, 3, 2, 4 };
Arrays.sort(values);
reverse(values);

Ideone Demo

您可以使用 Streamint 转换为 Integer,使用 Comparator 进行排序并将其重新转换为 int[]

final int[] values = {2, 0, 5, 1, 3, 4};
int[] reversed = IntStream.of(values)
    .boxed()
    .sorted(Comparator.reverseOrder())
    .mapToInt(i -> i)
    .toArray();
System.out.println(Arrays.toString(reversed));

输出:

[5, 4, 3, 2, 1, 0]