跟着官网的教程一起深入学习Lambda表达式:
lambda表达式是一种更简单的匿名类实例使用方式,有了lambda表达式就可以不用写匿名类实例了。在使用lambda表达式之前,你需要知道如下几点:
1.明确你要写的lambda表达式对应的类型
必须是只有一个抽象方法的接口,也就是除default方法和static方法外,只能有一个抽象方法,这样的接口叫做 functional interface
例如:
- @FunctionalInterface
- public interface Runnable {
- public abstract void run();
- }
Runnable接口,它有且只有一个抽象方法,注解@FunctionalInterface强调这是一个functional interface,但也可以不写这个注解
- @FunctionalInterface
- public interface Consumer
{ -
- void accept(T t);
-
- default Consumer
andThen(Consumer super T> after) { - // the body of this method has been removed
- }
- }
Consumer接口,有一个抽象方法和一个default方法,也符合functional interface标准
- @FunctionalInterface
- public interface Predicate
{ -
- boolean test(T t);
-
- default Predicate
and(Predicate super T> other) { - // the body of this method has been removed
- }
-
- default Predicate
negate() { - // the body of this method has been removed
- }
-
- default Predicate
or(Predicate super T> other) { - // the body of this method has been removed
- }
-
- static
Predicate isEqual(Object targetRef) { - // the body of this method has been removed
- }
-
- static
Predicate not(Predicate super T> target) { - // the body of this method has been removed
- }
- }
Predict接口,有一个抽象方法,还有多个default方法和static方法,也符合functional interface标准
2.明确lambda表达式要实现的方法
其实就是实现上面说的,接口里面的唯一抽象方法即可:
- public abstract void run();
-
- boolean test(T t);
-
- void accept(T t);
3.用lambda表达式实现接口方法
lambda表达式的基本语法:参数 -> 方法体,即由三分部组成
下面以实现Predict
假如我们需要获取一个Predict
- Predicate
predicate = - (String s) -> {
- return s.length() == 3;
- };
针对上面的代码,还可以简化lambda表达式:
(1)因为编译器知道这里入参类型肯定是String,所有入参可以省略调类型
(2)当只有一个入参时,可以省略掉括号(),但是多个入参和没有入参时必须要括号()
(3)方法体很简单时,通常指只有一句代码时,可以省略掉花括号{},并且可以省略掉return关键字
简化后的写法如下:
Predicate predicate = s -> s.length() == 3;
4.调用lambda表达式实现的实例方法
假如我们需要使用Predict的test方法过滤一个String列表,筛选出其中长度为3的字符串
- List
retainStringsOfLength3(List strings) { -
- Predicate
predicate = s -> s.length() == 3; - List
stringsOfLength3 = new ArrayList<>(); - for (String s: strings) {
- if (predicate.test(s)) {
- stringsOfLength3.add(s);
- }
- }
- return stringsOfLength3;
- }
5.lambda表达式只能访问外部的final变量

在lambda表达式中修改外部变量的值,编译不通过

在lambda表达式中访问外部非明确声明为final的变量,编译通过

在lambda表达式中访问外部明确声明为final的变量,编译通过

在lambda表达式中访问外部非final变量,但是在外面修改变量的值,编译报错
综合上面几种情况看,lambda表达式里面访问的外部变量必须明确声明为final或者不明确但是其他地方都不能修改该变量值