Java8新特性:Lambda表达式
Lambda表达式是一个匿名函数,即没有函数名的函数。在java 中表示的就是匿名方法。
1. 函数式接口
函数式接口,通常使用@FunctionalInterface注解标记,表示这是一个函数式接口并进行相应的语法检查。函数式接口有且仅有一个抽象方法,当然非抽象方法可以有多个。Java8中新增了java.util.function包,提供了很多函数式接口用来支持lambda表达式。
创建一个函数式接口:
public interface FunInterface {
int add(int a, int b);
}
2. Lambda表达式写法
lambda表达式就是对函数式接口中抽象方法的匿名实现,因为函数式接口中抽象方法有且仅有一个,所以可以进行匿名实现。
我们以上面的函数式接口为例,分别对add方法进行传统的方法实现和lambda表达式实现:
传统实现:
public int add(int a, int b) {
return a + b;
}
lambda表达式实现:
(int a, int b) -> {return a + b;}
以上面的案例为基础,说明一下lambda表达式的一些特征:
- 可选类型声明:参数的类型不需要声明,编译器可以统一识别。
- 可选的参数圆括号:单个参数无需使用圆括号,但是多个参数需要圆括号。
- 可选的大括号:如果方法体只有一个语句,那么可以省略大括号。
- 可选的返回值关键字:如果方法体只有一个语句(返回值),那么编译器会自动返回值,如果有大括号,需要指明返回了一个值。
按照上面的特征,对表达式进行变形:
// 可选类型声明
(a, b) -> {return a + b;}
// 可选参数圆括号,由于两个参数的原因,不能进行变形
// 可选的大括号和返回值关键字
(a, b) -> a + b
3. lambda 表达式简单使用
public class LambdaDemo {
public static void main(String[] args) {
// 1.传统方式实现函数式接口
FunInterface traditionalImpl = new FunctionalInterface() {
public int add(int a, int b) {
return a + b;
}
};
int result1 = traditionalImpl.add(1, 3);
// 2.lambda表达式实现函数式接口
FunctionalInterface lambdaImpl = (a, b) -> a + b;
int result 2 = lambdaImpl.add(1, 3);
// 验证结果
System.out.println("traditional: " + result1 + ", lambda : " + result2);
}
}
interface FunInterface {
int add(int a, int b);
}
对比可以发现,使用lambda表达式实现方法的代码量,要比使用匿名内部类实现方法的代码量要少很多。
4. 变量的作用域
在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
int a = 0;
FunIterface fi = (a, b) -> a + b; // 编译时会提示变量 'a' 已经被定义
lambda 表达式使用的局部变量可以不用声明为 final,但是必须不可被后面的代码修改
int num = 10;
FunInterface fi = (a, b) -> a + b + num; // 编译时会提示变量num需要是final修饰,或者具有final的效果,即用于表达式中的变量,一经声明不能修改
num = 5;