Lambda表达式在Java编程中的应用
2019-03-25任宪臻
任宪臻
摘 要:Lambda表达式是Java 8发布的最重要的新特性。在Java编程中,可以应用Lambda表达式替换匿名内部类,而且使用Lambda表达式可以使编写的Java代码看起来更加简短,使用起来也更加方便。应用Lambda表达式进行编程及应用Lambda表达式的场合是本文讲述的重点。
關键词:Lambda;表达式;函数式接口;匿名方法
中图分类号:TP312 文献标识码:A 文章编号:1671-2064(2019)03-0014-02
虽然Lambda表达式是JDK1.8引入的最重要的新增功能,但是其实在很多编程语言中都引入了Lambda表达式。其实简单来说,Lambda 表达式就是一个匿名方法,但是它又跟匿名方法不太一样。Lambda表达式在应用的时候,首先需要定义一个函数式接口。函数式接口也是JDK1.8中的新概念,它只允许有且仅有一个抽象方法,但是在函数式接口中,可以包含多个非抽象方法。
1 Lambda表达式的使用
Lambda表达式通常用表示如下:
(参数列表)->表达式,或者(参数列表)->{语句行;}
图1所示的例子展示了Lambda表达式的应用。从这个例子中,我们可以总结出在使用lambda表达式时要注意以下几点:
(1)在Lambda表达式中,编译器可以识别参数值类型,所以可以声明参数类型,也可以不声明。
(2)如果Lambda表达式只有一个参数,那么可以不必使用圆括号,但是如果有两个或两个以上的参数,必须把参数放到圆括号中,并且参数之间都用逗号间隔。
(3)如果Lambda表达式的主体部分只有一个语句,那么可以不需要使用大括号,但是如果有多个语句,则必须把所有语句放在大括号中。
(4)如果Lambda表达式只有一条语句返回值,那么可以省略return关键字,但是有多条语句并且有返回值,那么必须使用return关键字来返回值。
Lambda表达式主要用来定义类内执行的方法类型接口,所以在上面图1所示的例子中,我们使用各种类型的Lambda表达式来定义Arithmetic接口的方法。而且Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。
2 变量的引用
2.1 访问外层作用域定义的局部变量
lambda表达式可以访问外层作用域定义的局部变量,而且必须是经初始化的局部变量,但是它不能修改外层局部变量的值。即:lambda表达式的局部变量可以不用声明为final,但是具有隐性final的语义,所以变量值不能被修改,否则会报编译错误。因此,未初始化的外层局部变量不能被lambda表达式访问,也不能在lambda块内对其初始化。
因此,从图2例子中我们可以看出,使用Lambda表达式外层作用域定义的局部变量时,虽然该局部变量没有被显式声明修饰符为final,但是在Lambda表达式中访问此局部变量时,该变量自动会具有final的语义,这是编译器的需求,也就是说如果在Lambda表达式中访问的局部变量,如果不是final类型的话,编译器自动加上final修饰符。
2.2 获取或者更改外层类的属性
lambda表达式内可以通过this关键字(或不使用)访问或修改类的属性。但是如果外层类的属性是final标识的,则lambda内只能访问,不可以修改。而如果外层类的属性是static标识的,则仍然可以访问和多次修改。如图3例子所示。
上面我们讲述了Lambda表达式的普遍用法,而实际上在Java编程中,Lambda表达式可以使用了最少的代码量,实现了同样的功能。图4是使用匿名函数创建一个线程,而图5是使用Lambda表达式实现的同样功能的代码,从这两个例子中我们可以看到,应用Lambda表达式进行编程,可以让代码变得更加简洁、紧凑,很大程度上提升了Java的语言表达能力。
在Java程序中,使用Lambda表达式的好处就是极大地简化了代码,缩减了代码量,而且使程序逻辑也更加清晰明了。Lambda表达式一般适合于没有复杂逻辑或者无副作用的纯函数场景下,但是有的Lambda表达式会降低程序的可读性,虽然代码最大程度上简洁紧凑,但是产生的副作用就是有时候会使代码变得晦涩难懂。因此,虽然Lambda表达式最吸引人的地方是简洁,但是在有多层函数嵌套的情况下,Lambda表达式的简洁性并没有很大的提升,反而影响了函数的作用范围的识别度,这种情况下不建议使用Lambda表达式。