Java 8 中引入的 Lambda 表达式

Java 8 中引入的 Lambda 表达式极大地改善了 Java 的简洁性和可读性,特别是用于处理集合、流操作等场景。

Lambda 表达式可以看作是用来简化匿名内部类的一种简写方式。它可以直接作为接口实现被传递。Java 中,很多接口有且只有一个抽象方法,这些接口被称为 函数式接口(Functional Interface) 。例如 java.lang.Runnablejava.util.function 包中的接口,如 PredicateConsumer 等。

        • [Lambda 表达式的基本语法](#Lambda 表达式的基本语法)
          • [【示例 1】使用 Runnable 接口](#【示例 1】使用 Runnable 接口)
          • [【示例 2】使用 Comparator 接口](#【示例 2】使用 Comparator 接口)
        • [Java 内置的函数式接口](#Java 内置的函数式接口)
          • [【示例 3】使用 Predicate](#【示例 3】使用 Predicate)
          • [【示例 4】使用 Consumer](#【示例 4】使用 Consumer)
        • [Stream API 与 Lambda 表达式结合使用](#Stream API 与 Lambda 表达式结合使用)
          • [【示例 5】Stream API 的使用](#【示例 5】Stream API 的使用)
        • [Lambda 表达式的常用场景](#Lambda 表达式的常用场景)

Lambda 表达式的基本语法
java 复制代码
(parameters) -> expression
或
(parameters) -> { statements; }
  • 参数列表:列出传递给 Lambda 表达式的参数,多个参数用逗号分隔。如果参数类型可以从上下文推断,则可以省略类型。
  • 箭头符号->,用来分隔参数列表和 Lambda 表达式主体。
  • 表达式或代码块 :如果是单个表达式,结果会被自动返回。如果是多条语句,则需要使用大括号 {}

【示例 1】使用 Runnable 接口

传统上,使用匿名类来实现 Runnable 接口:

java 复制代码
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from Runnable using anonymous class!");
    }
};
new Thread(r1).start();

使用 Lambda 表达式后,代码可以简化为:

java 复制代码
Runnable r2 = () -> System.out.println("Hello from Runnable using Lambda!");
new Thread(r2).start();

或者更进一步:

java 复制代码
new Thread(() -> System.out.println("Hello from Runnable using Lambda!")).start();
【示例 2】使用 Comparator 接口

假设我们有一个 List<String>,想对其进行排序,传统方式是使用匿名类实现 Comparator

java 复制代码
List<String> names = Arrays.asList("John", "Alice", "Bob");

Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.compareTo(s2);
    }
});

使用 Lambda 表达式后可以简化为:

java 复制代码
Collections.sort(names, (s1, s2) -> s1.compareTo(s2));

进一步,我们可以直接使用 Listsort 方法:

java 复制代码
names.sort((s1, s2) -> s1.compareTo(s2));

Java 8 还提供了更简洁的方式,利用方法引用:

java 复制代码
names.sort(String::compareTo);

Java 内置的函数式接口

Java 8 引入了 java.util.function 包,包含一些常用的函数式接口,例如:

  • Predicate :接受一个参数,返回一个布尔值 (boolean)。
  • Consumer:接受一个参数,没有返回值。
  • Function<T, R>:接受一个参数,返回一个结果。
  • Supplier:没有参数,返回一个结果。

下面举一些使用这些函数式接口的例子:

【示例 3】使用 Predicate

假设我们想过滤一个整数列表,得到所有大于 5 的值,传统方式可能会这样写:

java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 6, 8, 10);
List<Integer> filteredNumbers = new ArrayList<>();
for (Integer number : numbers) {
    if (number > 5) {
        filteredNumbers.add(number);
    }
}

使用 Lambda 表达式和 Predicate 接口可以这样写:

java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 6, 8, 10);
List<Integer> filteredNumbers = numbers.stream()
                                       .filter(n -> n > 5)
                                       .collect(Collectors.toList());
System.out.println(filteredNumbers); // 输出: [6, 8, 10]
【示例 4】使用 Consumer

假设我们需要对一个列表的每个元素执行某些操作,比如打印它们:

java 复制代码
List<String> names = Arrays.asList("John", "Alice", "Bob");

// 使用 Lambda 表达式
names.forEach(name -> System.out.println(name));

// 使用方法引用
names.forEach(System.out::println);

Stream API 与 Lambda 表达式结合使用

Stream API 提供了一种函数式的编程方式来处理集合数据。

【示例 5】Stream API 的使用

假设我们有一个 List<String>,需要对其进行一系列操作:过滤掉长度小于 4 的字符串,将它们转换为大写,并收集到一个新的列表中。

java 复制代码
List<String> names = Arrays.asList("John", "Alice", "Bob", "David");

List<String> filteredNames = names.stream() // 创建 Stream
                                  .filter(name -> name.length() > 3) // 过滤长度大于 3 的名字
                                  .map(String::toUpperCase) // 转换为大写
                                  .collect(Collectors.toList()); // 收集结果

System.out.println(filteredNames); // 输出: [JOHN, ALICE, DAVID]

在这个例子中,filtermap 等方法都使用了 Lambda 表达式。


Lambda 表达式的常用场景
  • 集合操作:如排序、过滤、转换等。
  • 异步编程 :如简化 RunnableCallable 等接口的实现。
  • 事件处理:Lambda 非常适合用于 GUI 或者回调事件中,减少了编写事件监听器的样板代码。
相关推荐
许苑向上几秒前
最详细【Elasticsearch】Elasticsearch Java API + Spring Boot集成 实战入门(基础篇)
java·数据库·spring boot·elasticsearch
柳叶寒6 分钟前
医院信息化与智能化系统(17)
java·nacos·gateway·全栈·项目
首席架构师专栏7 分钟前
吊打面试官系列:final、finally、finalize 有什么区别?
java
hxj..17 分钟前
【算法】动态规划
java·算法·动态规划
世间万物皆对象30 分钟前
Java 基础教学:高级特性与实战-集合框架
java·开发语言
不爱吃米饭_33 分钟前
如何优雅处理异常?处理异常的原则
java·开发语言·spring boot
李少兄42 分钟前
IntelliJ IDEA 中创建目录时 `.` 和 `/` 的区别
java·ide·intellij-idea
V+zmm1013444 分钟前
社区养老服务小程序ssm+论文源码调试讲解
java·服务器·前端·javascript·小程序·毕业设计·1024程序员节
李少兄1 小时前
如何在 IntelliJ IDEA 中调整 `Ctrl+/` 快捷键生成注释的位置
java·ide·intellij-idea
豆本-豆豆奶1 小时前
给初学者的 Jupyter Notebook 教程
开发语言·python·jupyter·安装教程·notebook