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

huangapple go评论76阅读模式
英文:

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[]类型的一维数组进行排序。在互联网上,我找到了一些信息,其中提到:“对于原始数据类型的数组,按降序排序的唯一方法是,首先按升序对数组进行排序,然后在原地反转数组。”

为什么我能够对原始类型的二维数组进行排序,但不能使用比较器对一维数组进行排序呢?

英文:

I used the following code for sorting a 2D array of int[][] type in reverse order by making use of a comparator.

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

But I am unable to sort a 1D array of int[] type using similar approach. On the internet I found information saying "The only way to sort a primitive array in descending order is, first sort the array in ascending order and then reverse the array in place."

Why am I able to sort a 2D array of primitive type, but not a 1D array using comparator?

答案1

得分: 2

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

在更详细地查看Arrays API时,我们找到了方法sort(T[],Comparator<? super T>),它与Comparator中的一些静态构建方法一起,允许对对象数组进行逆向排序:

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

这仅适用于对象数组,而不适用于基本类型数组。对于基本类型数组,Arrays中没有任何sort(int[],Comparator<...>)方法(可能是因为不能将基本类型用作泛型类型,项目Valhalla可能会在将来更改这一点)。

因此,是的,如果要保持恒定的内存开销,对基本类型数组进行排序,然后对其进行反转似乎是唯一的选项。它可能看起来像这样(草图):

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

It is possible to sort an int[][] in descending order because one basically compares int[]s against each others. As per JLS, §10: "... Arrays are objects ...".

Looking closer at the Arrays API, we find method sort(T[], Comparator<? super T>), which, together with some static builder methods from Comparator, allows to reverse-sort an array of objects:

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

<kbd>Ideone Demo</kbd>

This only works for object-arrays, not for primitive arrays. And for primitive arrays, we do not have any method sort(int[], Comparator&lt;...&gt;) in Arrays (probably because one cannot use primitives as generic types, project Valhalla may or may not change this in the future).

So yes, sorting an array of primitives and then reversing it seems like the only option if one wants to have constant memory overhead. It would look something like this (sketch):

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

<kbd>Ideone Demo</kbd>

答案2

得分: 1

没有任何内置的排序方法接受一维原始数组和Comparator

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

  • 在Java程序中,原始数组本来就不常用。
  • 使用Comparatorsort实现需要将每个数组元素包装在对象中才能将它们传递给Comparator,因此用户可以自己将int数组转换为Integer数组。
  • 您需要添加7个或14个更多的Arrays.sort 实现,这是相当可观的代码量需要进行测试。
  • 自定义比较器的最常见用例是逆序排序,而您已经可以通过先排序,然后反转来实现。
英文:

There just aren't any built-in sort methods that accept a 1D primitive array and a Comparator.

As for why, only the designers can say authoratively, but here are some arguments against having them:

  • Primitive arrays are not used very often in Java programs to begin with.

  • A sort implementation that uses Comparator would need to wrap every array element in an object to pass them to the Comparator anyway, so you might as well have the user convert the array of int into an array of Integer themselves.

  • You would need to add 7 or 14 more Arrays.sort implementations which is a non-trivial amount of code to test

  • The most common use case for a custom comparator is sorting in reverse, and you can already achieve that by first sorting and then reversing

答案3

得分: 1

你可以使用 Stream 将一个 int 转换为一个 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]
英文:

You can use Stream to convert an int to an Integer, do sort using a Comparator and reconvert it to an int[].

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

output:

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

huangapple
  • 本文由 发表于 2020年8月15日 20:28:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63426038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定