6.8.2 Lambda表达式与函数式接口
6.8.2 Lambda表达式与函数式接口
Lambda
表达式的类型,也被称为”目标类型”(target type
)”,** Lambda
表达式的目标类型必须是”函数式接口(functional interface)"
**。
什么是函数式接口
函数式接口就是只包含一个抽象方法的接口。函数式接口可以包含多个默认方法、类方法,但只能声明一个抽象方法。
通过匿名内部类来创建函数式接口实例
如果采用匿名内部类语法来创建函数式接口的实例,则只需要实现一个抽象方法即可。
通过Lambda表达式来创建函数式接口实例
采用Lambda
表达式创建出来的对象的目标类型
就是这个函数式接口的类型。
java API中的函数式接口
查询Java8
的API
文档,可以发现大量的函数式接口,例如:Runnable
、 ActionListener
等接口都是函数式接口。
函数式接口注解
Java8
专门为函数式接口提供了@FunctionalInterface
注解,该注解通常放在接口定义前面,该注解对程序功能没有任何作用,它用于告诉编译器执行更严格检查—检查该接口必须是函数式接口,否则编译器就会报错。
使用Lambda表示式复制
由于Lambda
表达式的结果就是被当成对象,因此程序中完全可以使用Lambda
表达式进行赋值。
使用Lambda表达式创建线程执行体
Runnable
是Java
本身提供的一个函数式接口,所以可以直接使用Lambda
表达式来创建Runnable
实例。
1 | Runnable r = () -> { |
Lambda表达式的限制
Lambda
表达式实现的是匿名方法—因此它只能实现特定函数式接口中的唯一方法。这意味着Lambda
表达式有如下两个限制:
Lambda
表达式的目标类型必须是明确的函数式接口。Lambda
表达式只能为函数式接口创建对象。Lambda
表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口
创建对象。
如何保证Lambda表达式的目标类型一定是函数式接口
为了保证Lambda
表达式的目标类型是一个明确的函数式接口,可以有如下三种常见方式。
- 将
Lambda
表达式赋值给 函数式接口类型的引用变量 - 将
Lambda
表达式 作为函数式接口类型的参数 传给某个方法。 - 使用函数式接口对
Lambda
表达式进行强制类型转换
相同的Lambda表达式的目标类型可变 只要形参列表相同即可
同样的Lambda
表达式可以被当成不同的目标类型,唯一的要求是Lambda
表达式的形参列表与函数式接口中唯一的抽象方法的形参列表相同
。
Java8预定义的函数式接口及其作用
Java8
在java.util.function
包下预定义了大量函数式接口,典型地包含如下4类接口。
函数式接口 | 描述 |
---|---|
XxxFunction |
这类接口中通常包含一个apply() 抽象方法,该方法对参数进行处理、转换,然后返回一个处理后的新值。该函数式接口通常用于对指定数据进行转换处理。 |
XxxConsumer |
这类接口中通常包含一个accept() 抽象方法,该方法与XxxFunction 接口中的apply() 方法基本相似,也负责对参数进行处理,只是该方法不会返回处理结果。 |
XxxPredicate |
这类接口中通常包含一个test() 抽象方法,该方法通常用来对参数进行某种判断,然后返回一个boolean 值。该接口通常用于判断参数是否满足特定条件,经常用于进行筛滤数据 |
XxxSupplier |
这类接口中通常包含一个getAsXxx() 抽象方法,该方法不需要输入参数,该方法会按某种逻辑算法回一个数据。 |
Lambda表达式可以方便的创建函数式接口的实例
Lambda
表达式的本质很简单,就是使用简洁的语法来创建函数式接口的实例,这种语法可以避免创建匿名内部类的烦琐操作。