[英]Clarifying syntax on Lambda Expression
我使用下面的代码按列对二维数组进行排序,它在第二个参数中采用 lambda 表达式。 我不太明白 (a,b) 是如何定义的,以及 a[0] 和 b[0] 如何在比较器中工作。 此代码排序正确,但我想了解语法。 谢谢。
Arrays.sort(myArray, (a, b) -> Integer.compare(a[0], b[0]))
按列排列的二维数组
Java 没有二维 arrays。 它具有 arrays 或 arrays 和一些语法糖,可让您声明一个数组数组并通过创建新的 arrays 并填充插槽来立即初始化外部数组。
int[][] grid = new int[10][5];
是语法糖:
int[][] grid = new int[10][];
for (int i = 0; i < 10; i++) grid[i] = new int[5];
Arrays.sort(myArray, (a, b) -> Integer.compare(a[0], b[0]))
myArray 的类型是int[][]
。 换句话说,一个int[]
数组。 因此,要对此进行排序,您需要提供 oracle:此 oracle 需要能够对以下问题给出一致的答案:“给定 2 个组件(在这种情况下,该组件是int[]
),请告诉我第一个组件是否对第二个“之后”或第二个“之前”进行排序,或平均排序。通过返回一个负数来表示第一个是“之前”,一个正数表示第一个是“之后”,以及 0 到表明它们是相等的或至少在相同的级别上排序排序。
通常,您可以通过创建Comparator<int[]>
接口的实现、创建 this 的实例并传递它来做到这一点:
class MySorter implements Comparator<int[]> {
@Override public int compare(int[] a, int[] b) {
return Integer.compare(a[0], b[0]);
}
}
MySorter mySorter = new MySorter();
Arrays.sort(myArray, mySorter);
上面的代码工作正常——你可以编译并运行它。
Lambda 与上面发生的事情并没有太大的不同。 Arrays 上只有一种相关sort
方法,它确实需要 2 个 arguments:一个T
数组和一个可以比较T
的Comparator
,其中 T 是你喜欢的任何东西(这里, T 是int[]
)。 那么为什么你可以在那里传递一个 lambda 呢?
因为编译器是由外而内工作的。 它最初只是看到:
Arrays.sort(myArray, someLambdaExpressionIHaveNotLookedAtYet)
并且会停在那里,并尝试找出打算使用哪种方法。 它会发现只有一种方法“有效”: public static <T> sort (T[] array, Comparator<T> comparator)
。
只有这样 javac 才会继续:首先,它检查 Comparator 是否是所谓的“单一抽象方法”类型(SAM 类型):它是; Comparator 是一个只定义一个方法*的接口*,这意味着它是一个 SAM 类型,这意味着您可以将implements
此接口的 class 的创建以及创建此 class 的新实例的快捷方式创建为单行.
现在,因为java 已经知道 lambda 应该代表什么(即Comparator<int[]>
的实现,并且它知道您尝试实现的方法只有一种(即public int compare(int[] a, int[] b)
), java 已经知道变量类型。您要实现的方法必须是int[] a, int[] b
。
这就是您不必指定它的原因。 您可以只写(a, b)
- java 为您填写int[]
。 你可以写出来:试一试,写Arrays.sort(myArray, (int[] a, int b[]) -> Integer.compare(a[0], b[0])
你会找到它工作方式完全相同。
rest 是微不足道的: ->
只是 lambda 语法,并且因为您没有立即编写{
,所以 -> 后面的单个表达式只是作为返回值插入。
因此,
(a, b) -> Integer.compare(a[0], b[0])
100% 相当于:
public class A implements B {
public C {
return D;
}
}
A a = new A();
在哪里:
*) 已在 java.lang.Object 中定义的方法不计算在内,具有默认实现的方法也不计算在内。
Arrays.sort(T[] a, Comparator<? super T> c)
将Comparator<T>
作为第二个参数,它声明了方法int compare(T o1, T o2)
。
这意味着 lambda 表达式必须实现该方法,并且myArray
是Integer[][]
或int[][]
,这意味着T
是Integer[]
或int[]
,所以a
和b
都是Integer[]
或int[]
。
因此,该语句将按第一列对二维数组进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.