繁体   English   中英

澄清 Lambda 表达式的语法

[英]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数组和一个可以比较TComparator ,其中 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();

在哪里:

  • A = 随机选择的不相关名称,
  • B = 预期的类型
  • C = B 中定义的一种方法的副本(如果没有一种方法,则不能使用此语法),
  • D = 你在 -> 之后写的任何内容。

*) 已在 java.lang.Object 中定义的方法不计算在内,具有默认实现的方法也不计算在内。

Arrays.sort(T[] a, Comparator<? super T> c)Comparator<T>作为第二个参数,它声明了方法int compare(T o1, T o2)

这意味着 lambda 表达式必须实现该方法,并且myArrayInteger[][]int[][] ,这意味着TInteger[]int[] ,所以ab都是Integer[]int[]

因此,该语句将按第一列对二维数组进行排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM