1.语法
Lambda表达式语法由参数列表,箭头'->',函数体组成,函数体既可以是一个表达式,表达式会被执行,且会返回执行的结果,也可以是一个语句块。
举几个栗子
//接收2个参数,函数体是一个表达式
(int x, int y) -> x + y
//不接收参数,直接返回42
() -> 42
//接收1个参数,并打印。无返回值。
(String s) -> { System.out.println(s); }
更进一步的例子:
比如我们写了一个FileFilter如下:
// 原java 写法
FileFilter fileFilter = new FileFilter() {
@Override
public boolean accept(File f) {
return f.getName().endsWith(".java");
}
};
//Kotlin 中lambda写法:
var fileFilter:FileFilter = FileFilter { pathname-> pathname.absolutePath.endsWith(".java") }
//多行写法
var fileFilter: FileFilter = FileFilter { pathname -> var end = ".java"; pathname.absolutePath.endsWith(end) }
Lambda表达式阅读时可能有需要一些推导,需要根据上下文FileFilter,推导出函数体是在哪个接口里被调用的。
再举一个例子
// 原java 写法
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
return "done";
}
};
//Lambda表达式
Callable<String> callable = () -> "done";
2.函数体作用域
Lambda函数体作用域与外部一致
//以下main函数调用会输出两遍 "Hello, world"
public static class Hello {
Runnable r1 = () -> { System.out.println(this); };
Runnable r2 = () -> { System.out.println(toString()); };
public String toString() { return "Hello, world"; }
public static void main(String... args) {
new Hello().r1.run();
new Hello().r2.run();
}
}
Lambda对值封闭,对变量开放,如下:
int sum = 0;
list.forEach(e -> { sum += e.size(); }); //不合法,对值封闭
List<Integer> aList = new List<>();
list.forEach(e -> { aList.add(e); }); // 合法,对变量开发