划重点了:JAVA8之lambda表达式详解

一、什么是lambda表达式?

lambda表达式,是从JAVA8开始提供的一种新特性,它能够使JAVA支持简单的函数式编程(Functional Programming)。 lambda并非是Java首创,准确地来说,是Java迎合时代的产物。


划重点了:JAVA8之lambda表达式详解

lambda的好处很是易读,而且从语义上将更好理解,使用lambda表达式的好处就是代码量大大减少了!程序逻辑也很清晰明了。易读的好处带来的就是易维护,不容易出错,可以替代“内部匿名类”、可以对集合或者数组进行循环操作。它是一个匿名函数,也就是没有函数名的函数,Lambda表达式基于数学中的λ演算得名。

二、牛刀小试

例1:使用lambda表达式实现Runnable:


划重点了:JAVA8之lambda表达式详解

上述代码中:

() -> System.out.println("开始运行...")

就是一个lambda表达式,显而易见的是,这个lambda表达式替代了new Runnable(){}这个匿名内部类。

例2:使用lambda表达式来实现Comparator接口:


划重点了:JAVA8之lambda表达式详解

上述代码中:

(a, b) -> a.charAt(1) < b.charAt(1) ? 1:-1

就是一个lambda表达式,这个lambda表达式替代了new Comparator(){}这个匿名内部类。

例3:用lambda表达式实现ActionListener接口:


划重点了:JAVA8之lambda表达式详解

上述代码中:

e -> System.out.println("Hello!")

就是一个lambda表达式,这个lambda表达式替代了new ActionListener() {}这个匿名内部类。

三、lambda表达式的语法

Lambda的基本语法是:

(参数) -> lambda体

lambda是通过lambda运算符(->)连接的左右两部分,左边指定了lambda表达式所需要的所有参数,右边是lambda体,它指定了lambda表达式的动作,JAVA定了两种lambda体,一种包含单独的一个表达式,另一种包含一个代码块。我们先看第一种:


划重点了:JAVA8之lambda表达式详解

四、补充知识

要想继续学习Lambda,我们需要先补一下几个相关的知识点:

1. 类型推断


划重点了:JAVA8之lambda表达式详解

当我们在某个数字范围内提取一个值时,编译器知道该值的类型为 int。不需要在代码中显示的声明。

在 Java8 中我们可以丢弃 lambda 表达式中的类型:

IntStream.rangeClosed(1, 5).forEach((number) -> System.out.println(number * 2));

由于 Java 是静态类型语言,它需要在编译时知道所有的对象和变量的类型。在 lambda 表达式的参数列表中省略类型并不会让 Java 更接近动态类型语言。但是,添加适当的类型推断功能会让 Java 更接近其他静态类型语言,比如 Haskel 等

2. 变量捕获


划重点了:JAVA8之lambda表达式详解

简单地说,如果一个局部变量在初始化后从未被修改过,那么它就符合有效只读的要求, 换言之,加上final后也不会导致编译错误的局部变量就是有效只读变量。

3. 方法引用


划重点了:JAVA8之lambda表达式详解

方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文。计算时,方法引用会创建函数式接口的一个实例。

方法引用有很多种,它们的语法如下:

静态方法引用:ClassName::methodName
实例上的实例方法引用:instanceReference::methodName
超类上的实例方法引用:super::methodName
类型上的实例方法引用:ClassName::methodName
构造方法引用:Class::new
数组构造方法引用:TypeName[]::new

4. Functional接口


划重点了:JAVA8之lambda表达式详解

​Java SE 8中增加了一个新的包:java.util.function,它里面包含了常用的函数式接口:

Predicate——接收T对象并返回boolean
Consumer——接收T对象,不返回值
Function——接收T对象,返回R对象
Supplier——提供T对象(例如工厂),不接收值
UnaryOperator——接收T对象,返回T对象
BinaryOperator——接收两个T对象,返回T对象

那么在参数为这些接口的地方,我们就可以直接使用lambda表达式了!

五、优缺点

1)Lambda的优点:

a. 极大的简化代码。去除了很多无用的Java代码,使得代码更为简洁明了。

b. 比匿名内部类更加高效(不确定)。编译器会生成专门的lambda方法,可以使用javap -p查看编译过后的代码

2) Lambda的缺点:

可读性差,在代码简洁的情况下,另一方面又让大多程序员很难读懂。因为很少程序员接触使用它。

六、实际开发中的使用例子:

例子:自定义Functional接口,从而使用lambda表达式:

首先自定义一个函数式接口:


划重点了:JAVA8之lambda表达式详解

在我们自定义的函数式接口的地方使用lambda表达式:


划重点了:JAVA8之lambda表达式详解

例二:使用方法引用( ClassName::Method)


划重点了:JAVA8之lambda表达式详解

例三:使用lambda表达式完成for-each循环操作


划重点了:JAVA8之lambda表达式详解


分享到:


相關文章: