lambda scopes
在lambda表达式中我们可以访问外部变量,这个功能和匿名内部类一样,但是对于匿名内部类,我们只能访问final变量,lambda表达式中都可以访问,但是它只是隐式地将变量变成了final
首先我们能通过lambda表达式来访问外部变量。
1 |
|
但是我们不能再改变lambda表达式中调用的外部变量了,因为一旦被lambda表达式调用,这个变量就被隐式地声明成了final变量。
1 |
|
这个时候就会报错 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量。
还有一个容易混淆的点就是这样的写法
1 | public static void main(String[] args) { |
即使是对象也是一样
1 |
|
这个时候其实我们只是将num作为函数参数传进去了,在lambda表达式中并没有显示声明调用这个变量。
在lambda表达式中我们还可以访问静态和类中的字段
1 | class Lambda4 { |
还记得上次声明的Formula接口么,其中定义了一个sqrt的默认方法,在lambda中我们是不能调用默认方法的。
1 | Formula formula = (a) -> sqrt(a * 100); //这样编译不通过 |
Built-in Functional Interfaces
Predicate
这是断言,判断的意思。先上代码
1 | Predicate<String> predicate = (s) -> s.length() > 0; |
其中test方法就是Predicate接口中的唯一抽象方法,我们lambda表达式中就是实现了它。
negate方法是取反的意思,其中还有and(), or()这两个默认方法对应语,或。
可以直接看源代码
1 |
|
Function
Function从字面理解就是函数的意思,这也是Java支持函数式编程的一个很重要的函数式接口。我们先看源码。
1 |
|
其中apply()是我们需要实现的一个函数,为什么这里说是函数不是方法呢?我们现在用函数式的思想去思考这个问题,其实这个方法就是我们给定一个参数然后我们返回一个结果,具体这个函数是怎么实现我们先不管。这就是函数式思想(先考虑参数和结果,然后再去考虑实现行为)。
这是作者给的实例代码
1 | // 这里是实现apply方法 |
这里多出来了个andThen方法,我们来具体看一看
1 | default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { |
里面还有一个compose方法,其实和andThen方法正好相反
1 | default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { |
Supplier
这个函数很简单,就相当于无参函数,我们不需要设置给定参数,只关注结果
具体源码也很简单
1 |
|
1 | Supplier<Person> personSupplier = Person::new; |
Comsumer
我们先来看一下源码
1 |
|
上面有一个accept()是我们需要实现的抽象方法,其实就是我们给定一个参数但是我们没有返回值,然后这个andThen()就是传入一个Consumer先调用原来的Consumer的accept方法然后再调用传入的accept()
Comparators
1 | // 这里是实现了compare方法 |