如何编写比较器以使用Lambda表达式基于第二列对2D数组排序

时间:2019-07-05 15:05:18

标签: lambda java-8 comparator

我正在研究Java中的二维数组排序问题。我想基于每一行的第二列(例如a [i] [1])对数组进行排序。我试图编写一个lambda表达式以将其放在Arrays.sort(a,比较器)中,以避免编写整个类。

这是我尝试过的:

Arrays.sort(contests, (int[] num1, int[] num2) -> Integer number1 = num1[1];
   Integer number2 = num2[1];
    return number2.compareTo(number1);
);

我不确定出什么问题了,因为Java在运行时不会给出确切的错误消息。我知道lambda表达式的第一部分是输入,第二部分是比较。由于.compareTo()仅适用于对象,因此创建了两个Integer。 Eclipse不断告诉我要插入;在整数之后。有人可以帮我吗?谢谢

3 个答案:

答案 0 :(得分:2)

lambda表达式中的类型定义来自上下文,不需要其他类型定义。
您的示例仅使用数组contests[1]中的值。
Arrays.sort()需要一维数组。
如果将contests定义为Integer[][] array,则此表达式应适用于您:

Arrays.sort( contests[1], (num1, num2) -> ( num2.compareTo( num1 ) ) );


要对两个对应的数组进行排序-Arrays.sort()不起作用:

index1 = 0;  // defined as class variable
index2 = 0;  // defined as class variable
Arrays.stream( contests[1] ).map( (n) -> new Integer[] {
    contests[0][index1], contests[1][index1++]
} ).sorted( (arr1,arr2) -> Integer.compare( arr2[1], arr1[1] ) )
.forEach( (arr) -> {
  contests[0][index2] = arr[0];
  contests[1][index2++] = arr[1];
} );

一种方法是将contests[0]的对应值(相同索引)与contests[1]配对,并将这些数组映射到contest[1]值。
排序后,将值写回到forEach循环中。

答案 1 :(得分:1)

在查看Arrays.sort(array, comparator)的文档时,发现比较器比较类型T的对象时,输入数组必须具有Class作为类型。

public static <T> void sort(T[] a, Comparator<? super T> c)

因此,以这种方式对2D数组进行排序将需要更多的精力来使结构协同工作。

或者,由于此过程中会发生自动装箱,因此可以使用Streams来实现目标。这是根据您的要求使用Streams和lambda的解决方案:

int[][] contests = { { 1, 7 }, { 2, 5 }, { 3, 2 }, { 4, 3 } };
Arrays
  .stream(contests)
  .sorted((a1, a2) -> a1[1] - a2[1])
  .forEach(a -> System.out.println(Arrays.toString(a)));

可以在此处找到有效的示例:https://repl.it/@randycasburn/2D-array-sort

答案 2 :(得分:0)

Arrays.sort(contests,(int[] num1,int[] num2)->Integer.compare(num2[1],num1[1]));

这对我有用。