Java 8 Lambda 写法与简化
Java 8 的 Lambda 表达式的实现方式还是基于已有的字节码指令,由 Lambda 表达式的方法签名结合上下文并经由 SAM 推断出正确的类型来。Java 8 的 Lambda 完整书写格式是
这种标准格式所表示的就是方法签名。
虽不及其他语言的 Lambda 表达式,像 Swift, Scala 可省略参数部分,可用默认参数名
. 参数类型总是可省略, 基本上我们总是省略掉参数类型
. 参数为一个时,参数括号省略
. 语句为一条时,可省略大括号, 并且语句后不要分号
. 如果是单条 return 语句,省去大括时必须把 return 关键字去掉
. 参数部分的括号总是需要
不写出
Java 8 中目前还无法简化成类似于 Swift/Scala 中的 foo(System.out.println()) 或 foo {System.out.println()}。不过可以采用方法引用的方式,只是方法引用有其缺陷--不能捕获外部变量。
前面说过用方法引用的缺陷是无法捕外部变量,譬如用 Lambda 的方式
而在前面的 todo 方法中却访问不到 external 变量,如果给 todo 再增加一个参数来传递 external 则不符合 Function 的 SAM 的签名了。
除非,除非用实例的方法引用,那么需要每次传入外部参数来构造实例,例如这样
这样着实有些怪异,而且有点把欲作简化的东西复杂化了。 永久链接 https://yanbin.blog/java-8-lambda-simple-ways/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
(type parameter1 [type parameter2, ...type parametern]) -> { statements here }这种标准格式所表示的就是方法签名。
虽不及其他语言的 Lambda 表达式,像 Swift, Scala 可省略参数部分,可用默认参数名
$0, $1, 或 _, 但 Java 8 的 Lambda 还是可以进行酌情简化- 参数类型总是可省略 --
(x, y) -> { x + y; } - 参数为一个时,参数括号可省略 --
x -> { System.out.println(x); } - 语句为一条时,可省略大括号, 并且语句后不要分号 --
x -> System.out.println(x) - 上面更进一步,如果是单条 return 语句,必须把 return 关键字去掉 --
x -> "Hello " + x - 就差一点,参数部分总是不能省,无参必须写成
() -> System.out.println("hi") - Java 8 中若要近似的实现无参数部分写法,那就是方法引用了 --
System.out::println
. 参数类型总是可省略, 基本上我们总是省略掉参数类型
1interface Function {
2 void call(String x, String y);
3}
4
5void foo(Function f) {
6 f.call("a", "b");
7}
8
9foo((x, y) -> { //(x, y) 完整写法是 (String x, String y)
10 System.out.println(x);
11 System.out.println(y);
12});. 参数为一个时,参数括号省略
1interface Function {
2 void call(String x);
3}
4
5Function f = x -> {
6 System.out.println();
7 System.out.println(x);
8};
9f.call("Hello");. 语句为一条时,可省略大括号, 并且语句后不要分号
1interface Function {
2 void call(String x);
3}
4
5void foo(Function f) {
6 f.call("Hi");
7}
8
9foo(x -> System.out.println(x)); //不能写成 foo(x -> System.out.println(x);); 这像话. 如果是单条 return 语句,省去大括时必须把 return 关键字去掉
1interface Function {
2 void String call(String x);
3}
4
5foo(x -> "Hello " + x). 参数部分的括号总是需要
1interface Function {
2 void call();
3}
4
5Function f = () -> System.out.println();不写出
-> 来似乎不知道这是一个 Lambda.Java 8 中目前还无法简化成类似于 Swift/Scala 中的 foo(System.out.println()) 或 foo {System.out.println()}。不过可以采用方法引用的方式,只是方法引用有其缺陷--不能捕获外部变量。
1public class TestLambda {
2
3 public static void main(String[] args) {
4 foo(TestLambda::todo); //todo 方法的签名正好是 x -> String
5 }
6
7 static void foo(Function f){
8 System.out.println(f.call("World"));
9 }
10
11 static String todo(String x) { //也就是这个方法正好符合 Function 的 SAM 方法签名
12 return "Hello " + x;
13 }
14}
15
16interface Function {
17 String call(String x);
18}前面说过用方法引用的缺陷是无法捕外部变量,譬如用 Lambda 的方式
1String external = "ABC";
2foo(x -> external + x);而在前面的 todo 方法中却访问不到 external 变量,如果给 todo 再增加一个参数来传递 external 则不符合 Function 的 SAM 的签名了。
除非,除非用实例的方法引用,那么需要每次传入外部参数来构造实例,例如这样
1public class TestLambda {
2
3 public static void main(String[] args) {
4 String external = "ABC";
5 foo(new MethodProvider(external)::todo); //输出 Hello ABC World
6 }
7
8 static void foo(Function f){
9 System.out.println(f.call("World"));
10 }
11}
12
13class MethodProvider {
14 private String _external;
15
16 public MethodProvider(String external) {
17 this._external = external;
18 }
19
20 String todo(String x) {
21 return "Hello " + _external + " " + x;
22 }
23}
24
25interface Function {
26 String call(String x);
27}这样着实有些怪异,而且有点把欲作简化的东西复杂化了。 永久链接 https://yanbin.blog/java-8-lambda-simple-ways/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。