莫度编程网

技术文章干货、编程学习教程与开发工具分享

Java新特性:Lambda表达式_java中的lambda表达式

1、Lambda表达式概述

1.1、Lambda表达式的简介

Lambda 表达式(Lambda expression),也可称为闭包(Closure),是 Java(SE)8 中一个重要的新特性。

Lambda 表达式允许我们通过表达式来代替功能接口。Lambda 表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)

Lambda 表达式可以看作是一个匿名函数,基于数学中的 λ 演算得名。

1.2、Lambda表达式的语法

Lambda 表达式的基本语法:

(parameters) -> expression 或 (parameters) -> { statements; }

Lambda 表达式的三个组成部分:


1、参数列表(parameters):类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明,也可不声明而由 JVM 隐含的推断。另外当只有一个推断类型时可以省略掉圆括号;

2、箭头(->):连接参数列表和 Lambda 主体,可理解为"被用于"的意思;

3、Lambda 主体(expression 或 { statements; }):可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不反回。

Lambda 表达式样例:



1.3、Lambda表达式的要求

虽然说,Lambda 表达式可以在一定程度上简化接口的实现。但是,并不是所有的接口都可以使用 Lambda 表达式来简洁实现的。

Lambda 表达式毕竟只是一个匿名方法。当实现的接口中的方法过多或者多少的时候,Lambda 表达式都是不适用的。

Lambda 表达式,只能实现函数式接口。

2、函数式接口

2.1、什么是函数式接口

如果说,一个接口中,要求实现类必须实现的抽象方法,有且只有一个!这样的接口,就是函数式接口。

代码如下(示例):


或者(示例):


2.2、函数式接口注解(@FunctionalInterface)

在接口之前,我们可以使用 @FunctionalInterface 注解来判断这个接口是否是一个函数式接口。,用如果是函数式接口,没有任何问题。如果不是函数式接口,则会报错。功能类似于 @Override。

代码如下(示例):



3、Lambda表达式的使用

3.1、Lambda表达式的基本使用

例1(无参数无返回值):



例2(一参数无返回值):


例3(多参数无返回值):


例4(无参数有返回值):



例5(一参数有返回值):


例6(多参数有返回值):


3.2、Lambda表达式的语法精简

Lambda 表达式的语法精简:

参数类型可以省略,如果需要省略,每个参数的类型都要省略;

参数的小括号里面只有一个参数,那么小括号可以省略;

如果方法体当中只有一句代码,那么大括号可以省略;

如果方法体中只有一条语句,其是 return 语句,那么大括号可以省略,且去掉 return 关键字。

4、变量捕获

Lambda 表达式中存在变量捕获,了解了变量捕获之后,我们才能更好的理解 Lambda 表达式的作用域。Java 当中的匿名类中,会存在变量捕获。

4.1、匿名内部类的变量捕获

所谓变量捕获就是:匿名内部类中访问所在方法或代码块中的局部变量,这个过程被称为 “变量捕获”。


但是,只有在局部变量是 “有效的最终变量” 时,匿名内部类才能够引用它。如果局部变量不是有效的最终变量,则无法在匿名内部类中引用它,会导致编译错误。

有效的最终变量指的是一个在生命周期中没有被修改过的局部变量,它可以被认为是一个常量。

4.2、Lambda的变量捕获

同样的,Lambda 的变量捕获也是只有在局部变量是 “有效的最终变量” 时,才能够引用它。


4.3、匿名内部类的变量捕获与Lambda的变量捕获的区别

区别:Lambda 表达式可以捕获外面的 this,而匿名内部类无法直接捕获外面的 this。

在 Lambda 表达式中,this 关键字引用的是 Lambda 表达式所在的类的实例,而不是 Lambda 表达式内部的类的实例。这个特性被称为 “闭包”。

匿名内部类中的 this 关键字引用的是匿名内部类的实例,而不是外部类的实例。


如果想让匿名内部类的捕获外面的 this,就需要使用外部类的类名或对象引用来访问。


5、Lambda 在集合当中的使用

为了能够让 Lambda 和 Java 的集合类集更好的一起使用,集合当中,也新增了部分接口,以便与 Lambda 表达式对接。


5.1、Collection接口中的forEach()方法

这个方法是在接口 Iterable 当中的:


这个方法表示用于对集合中的每个元素执行指定的操作。


5.2、List接口中的sort()方法

List 接口中的 sort() 方法:


该方法根据 c 指定的比较规则对容器元素进行排序。可以看到其参数是 Comparator,我们点进去看下:又是一个函数式接口:


使用示例:


修改为 Lambda 表达式:


5.3、Map接口的forEach()方法

HashMap 的 forEach() 方法:


可以看到这个方法有一个 BigConsumer,并且这也是一个函数式接口:


代码示例:


修改为 Lambda 表达式:


控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言

    Powered By Z-BlogPHP 1.7.4

    蜀ICP备2024111239号-43