145. Java Lambda 表达式
1. Lambda 表达式概述
在 2014 年发布的 Java SE 8 版本中,Java 语言引入了 Lambda 表达式的概念。
在 Java 8 之前,如果你想创建一个只用于一次性使用的类实例,通常会使用 匿名类(Anonymous Classes)。Lambda 表达式可以看作是匿名类的一种简化形式,在某些特定场景下可以替代匿名类,使代码更加简洁和可读。
为什么需要 Lambda 表达式?
如果你曾经使用过 匿名类,你可能会觉得它的语法冗长且不够直观。例如,在 Java 8 之前,我们这样写一个匿名类:
// 传统的匿名类实现 Runnable 接口
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, Lambda!");
}
};
使用 Lambda 表达式后,代码更加简洁:
Runnable runnable = () -> System.out.println("Hello, Lambda!");
Lambda 表达式不仅减少了代码量,也提升了可读性,使 Java 更加现代化。
2. 如何编写 Lambda 表达式?
编写 Lambda 表达式需要理解以下 三个步骤:
- 确定
Lambda表达式的类型(即它所实现的接口) - 找到正确的方法进行实现
- 实现该方法
2.1 确定 Lambda 表达式的类型
在 Java 语言中,每个表达式都有一个确定的类型,并且这个类型在 编译期 就已经确定。Lambda 表达式的类型通常是 变量的类型、方法的参数类型或方法的返回值类型。
Lambda 表达式的类型必须是 函数式接口(Functional Interface),即 只有一个抽象方法的接口。如果接口包含多个抽象方法,那么它就不能用于 Lambda 表达式。
2.2 什么是函数式接口?
函数式接口 是指 只包含一个抽象方法 的接口。
Java 8允许在接口中定义默认方法(default方法)和静态方法(static方法),但这些方法不影响接口是否为函数式接口。
在 Java 8 中,我们可以使用 @FunctionalInterface 注解来显式声明一个接口是 函数式接口,但这并不是必须的。即使不加该注解,Java 也会自动识别符合条件的接口。
2.3 例子:Java 内置的函数式接口
示例 1:Runnable(无参数无返回值)
@FunctionalInterface
public interface Runnable {
void run();
}
Lambda 实现:
Runnable r = () -> System.out.println("Lambda Running!");
r.run();
示例 2:Consumer(有参数无返回值)
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
// 省略方法体
}
}
Lambda 实现:
Consumer<String> consumer = s -> System.out.println("Hello, " + s);
consumer.accept("Lambda"); // 输出:Hello, Lambda
示例 3:Predicate(有参数有返回值)
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
// 省略方法体
}
}
Lambda 实现:
Predicate<Integer> isEven = num -> num % 2 == 0;
System.out.println(isEven.test(10)); // 输出:true
System.out.println(isEven.test(11)); // 输出:false
3. 如何实现 Lambda 表达式?
当你确定了 Lambda 表达式的类型(即所实现的函数式接口)后,就可以编写对应的 Lambda 实现。
Lambda 表达式的语法
Lambda 表达式的基本语法如下:
(parameters) -> { body }
语法规则:
parameters:参数列表,可以省略参数类型。->:Lambda运算符。{ body }:方法体,如果只有一条语句,可以省略{}。
示例:不同形式的 Lambda 表达式
1. 无参数,无返回值
Runnable r = () -> System.out.println("Hello, Lambda!");
r.run();
2. 一个参数,无返回值
Consumer<String> printer = message -> System.out.println(message);
printer.accept("Hello World");
3. 多个参数,有返回值
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
System.out.println(add.apply(10, 20)); // 输出:30
4. 代码块形式(带 {} 和 return)
BiFunction<Integer, Integer, Integer> multiply = (a, b) -> {
int result = a * b;
return result;
};
System.out.println(multiply.apply(3, 5)); // 输出:15
4. 总结
Lambda 表达式是 Java 8 中的重要特性,它让 Java 语言更加简洁和现代化。要掌握 Lambda 表达式,你需要记住:
Lambda表达式只能用于函数式接口(即只有一个抽象方法的接口)。- 常见的函数式接口包括
Runnable、Consumer<T>、Predicate<T>等。 Lambda表达式的语法简洁,可以省略参数类型和{}。
通过 Lambda 表达式,我们可以写出更简洁、可读性更强的代码,使 Java 代码更加优雅和高效。🚀