145. Java Lambda 表达式

67 阅读3分钟

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 表达式需要理解以下 三个步骤

  1. 确定 Lambda 表达式的类型(即它所实现的接口)
  2. 找到正确的方法进行实现
  3. 实现该方法

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 表达式,你需要记住:

  1. Lambda 表达式只能用于函数式接口(即只有一个抽象方法的接口)。
  2. 常见的函数式接口包括 RunnableConsumer<T>Predicate<T> 等。
  3. Lambda 表达式的语法简洁,可以省略参数类型和 {}

通过 Lambda 表达式,我们可以写出更简洁、可读性更强的代码,使 Java 代码更加优雅和高效。🚀