Java8基础知识(四)lambda表达式
lambda表达式
lambda表达式的形式:(parameters) -> expression或(parameters) -> {statements;}。
其本质是匿名函数,用于延迟执行,即代码不会立即执行且不再执行的情况。
函数式接口
当一个接口仅有一个抽象方法时,称其为函数式接口。当一个对象方法需要这种接口作为参数时,可以使用lambda表达式代替。
最常用的函数式接口有Runnable、Supplier、Consumer、Function和Predicate等。
| 函数式接口 | 参数类型 | 返回类型 | 抽象方法名 | 描述 |
|---|---|---|---|---|
| Runnable | 无 | 无 | run | 执行动作 |
| Supplier |
无 | T | get | 提供T类型的值 |
| Consumer |
T | 无 | accept | 处理T类型的值 |
| Function<T, R> | T | R | apply | T类型为参数的函数,返回R类型 |
| Predicate |
T | boolean | test | T类型为参数的布尔值函数 |
示例代码如下:
package lambda;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class FunctionalInterfaceTest {
public static void main(String[] args) {
repeat(10, () -> System.out.println("Repeat!"));
System.out.println(getName(() -> "Supplier!"));
showName("Consumer!", (str) -> System.out.println(str));
System.out.println(getLength("Function!", (str) -> str.length()));
System.out.println(isPredicate("Predicate!", (str) -> str.equals("Predicate!")));
}
public static void repeat(int n, Runnable action) {
for(int i=0; i<n; i++)
action.run();
}
public static String getName(Supplier<String> supplier) {
return supplier.get();
}
public static void showName(String name, Consumer<String> consumer) {
consumer.accept(name);
}
public static int getLength(String str, Function<String, Integer> function) {
return function.apply(str);
}
public static boolean isPredicate(String str, Predicate<String> predicate) {
return predicate.test(str);
}
}
方法引用
某些lambda表达式等价于方法引用。方法引用有三种:
- object::instanceMethod
- Class::staticMethod
- Class::instanceMethod
前两种情况等价于提供方法参数的lambda表达式,对于第三种情况,第一个参数会成为调用该方法的实例。
注:也可以使用this和super作为引用方法的类。
class Greeter {
public void greet() {System.out.println("Hello!");}
}
class TimedGreeter extends Greeter {
public void greet() {
// 引用父类的方法
Timer t = new Timer(1000, super::greet);
t.start;
}
}
构造器引用
可以引用new方法来构造类的实例。
由于Java限制无法构造泛型数组,可以通过数组构造器引用克服这一限制。
// toArray方法返回Object数组,无法强制类型转换
Object[] people = stream.toArray();
// 利用构造器引用可以使toArray方法提供正确类型的数组
Person[] people = stream.toArray(Person::new);
变量作用域
lambda表达式存在限制:
- 表达式的体与嵌套块有相同的作用域。
- 表达式捕获的变量(外围作用域中变量)必须是最终变量,即变量初始化之后值不会改变。
- 表达式使用的
this关键字,指创建这个表达式的方法的this参数。

浙公网安备 33010602011771号