简介
编程特性
- 不可变
- 好处:
- 不需要考虑并发的问题
- 把对象的状态变化拆解开来,大大减少了出现BUG的可能性
- 好处:
- 惰性求值
- 闭包
- 高阶函数
- 传入一个函数然后返回一个函数
- 柯里化
- 部分应用
- 结合率
适用场景
- 创建线程
- 策略模式,如comparator
- UI 编程
- 异步回调
- ...
Lambda表达式
使用lambda表达式的一般语法是
(Parameters) -> { Body }
-> 分隔参数和lambda表达式主体。
参数括在括号中,与方法相同,而lambda表达式主体是用大括号括起来的代码块。
注意
-
lambda表达式主体可以有局部变量,语句。我们可以在lambda表达式主体中使用break,continue和return。我们甚至可以从lambda表达式主体中抛出异常。
-
lambda表达式没有名称,因为它表示匿名内部类。
-
lambda表达式的返回类型由编译器推断。
-
lambda表达式不能像方法一样有throws子句。
-
lambda表达式不能是泛型,而泛型在函数接口中定义。
隐式lambda表达式
未声明其参数类型的lambda表达式称为隐式lambda表达式。
语法糖
函数式接口
lambda表达式表示函数式接口的实例。
lambda表达式的类型是一个函数式接口类型。
Java中万物皆对象,所以lambda表达式实际是创建了一个函数式接口的对象。
注意
- lambda表达式本身不能用作独立的表达式。
- lambda表达式的类型由编译器推断。
- 我们不能使用以下类型的方法来声明一个函数式接口:
- 默认方法
- 静态方法
- 从Object类继承的方法
- 例如:java.util.Comparator接口中有两个抽象方法:
compare()和equals(),equals()方法是Object类中的equals()方法的重新声明。
- 例如:java.util.Comparator接口中有两个抽象方法:
内置常用函数式接口
| 输入 | 返回值 | class |
|---|---|---|
| T | R | Function< T, R > |
| void | T | Supplier< T > |
| T | void | Consumer< T > |
| void | void | Runnable |
| T | Boolean | Predicate< T > |
| T | T | UnaryOperator< T > |
方法引用
这种方法引用方式有些难理解,如上图所示,接口FN中的apply方法接收的参数是arg1...argN,其中arg1的类型为T,T类型中有个方法tMethod,它接收的参数是arg2...argN,当我们需要一个FN接口时,正常的调用是(arg1...argN) -> {},还可以传比FN接口方法少一个参数的方法(只能少一个参数,且少的参数必须是第一个,并且这个少参方法的类型必须是FN接口中apply方法的第一个参数的类型,在上图中即是T), 上图中 T 的tMethod方法 即可以传递给接口FN,当调用FN中的apply方法时,第一个参数arg1作为实例T,
剩下的arg2...argN作为参数传给tMethod。