java 闭包( lambda表达式)
2021-09-12 本文已影响0人
zhbi98
1. lambda表达式简介
闭包也被称为 lambda 表达式,让您能够使用运箭头算符“->”来创建只有一个方法的类的对象,它是推动 Java 8 发布的最重要新特性,使用 Lambda 表达式可以使代码变的更加简洁紧凑,典型的应用是JavaFX的事件响应函数
lambda表达式格式:
(形式参数) -> {代码块}
例如最简单的lambda表达式:
Runnable runner = () -> { System.out.println("Hello,World!"); };
即:
Runnable runner = () -> {
System.out.println("Hello,World!");
};
2. lambda表达式的简化
其实lambda表达式和匿名内部类是相似的,可以认为lambda表达式就是由匿名内部类简化而来。
Interface01这是一个接口,现在使用匿名内部类来实现接口中的方法如下:
Interface01这是一个接口
Interface01 interface01 = new Interface01() {
@Override
public void show() {
System.out.println("啦啦啦");
}
};
interface01.show();
在匿名内部类的写法中,我们知道new的一定是个接口,所以需要省略接口名和大括号,所以得到如下:
image.png
因为接口内部只有一个抽象方法,所以需要省略抽象方法的名称、修饰符、返回值,所以得到如下:
image.png
结合Lambda的格式(形式参数) -> {代码块},在参数的小括号和代码块的大括号中间加 -> 符号,所以得到如下:
Interface interface01 = ()->{System.out.println("啦啦啦")}
3. 带参数的lambda表达式
设存在一个接口Interface02如下:
public interface Interface02 {
int add(int a, int b);
}
lambda表达式实现接口:
Interface02 interface02 = (int a,int b) -> {
return a+b;
};
interface02.add(1,2);
参数类型可以省略,但不能只省略一部分【如改为(int a,b)】
Interface02 interface02 = (a, b) -> {
return a+b;
};
interface02.add(1,2);
如果代码块语句只有一行,可以省略大括号和分号。如果这一行包括return,return也必须要省略
Interface02 interface02 = (a, b) -> a+b;
interface02.add(1,2);
如果参数只有一个,可以省略参数的小括号
Interface03 in03 = (a) -> System.out.println(a);
即:
Interface03 in03 = a -> System.out.println(a);
4. lambda表达式实现接口
interface Proudcts {
public void proudcts();
}
class GoogleProudct {
GoogleProudct(Proudcts pd) {
pd.proudcts();
}
}
interface Addition2 {
public void addition2(int a, int b);
}
class Sum {
Sum(Addition2 addt) {
addt.addition2(10, 20);
}
}
interface Addition {
public int addition(int a, int b);
}
public class LambdaLearn {
public static void main(String[] args) {
/**
* Use lambda to implement an interface
* with only one abstract method
*/
GoogleProudct gp = new GoogleProudct(() -> {
System.out.println("Android OS 10");
});
/**
* (argument) -> (body)
* (arg1, arg2...) -> { body }
*/
Sum sum = new Sum((i, j) -> {
System.out.println(i + j);
});
/**
* (argument) -> (body)
* (arg1, arg2...) -> { body }
*/
Addition additions = (i, j) -> {
return i + j;
}; // Addition additions = (i, j) -> i + j;
System.out.println("Addition:" + additions.addition(100, 200));
additions = (i, j) -> (i + j); // Addition addition = (i, j) -> {return(i + j)};
System.out.println("Addition:" + additions.addition(300, 500));
}
}
5. 注意事项
使用Lambda必须要有上下文环境,如果没有相应的前因后果,编译器也不知道我们表达是具体是哪个接口。编译器可以通过根据局部变量的赋值得知
Runnable r = ()-> xxxx;
根据调用方法的参数得知
new Thread(()-> xxxx).start();