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 或者回调事件中,减少了编写事件监听器的样板代码。
相关推荐
半桶水专家10 分钟前
C语言中的setitimer函数详解
c语言·开发语言·算法
失散1311 分钟前
分布式专题——26 BIO、NIO编程与直接内存、零拷贝深入辨析
java·分布式·rpc·架构·nio·零拷贝
zhangfeng113328 分钟前
R语言 安装老一点的班装包 核心是从CRAN归档(Archive)下载对应版本的安装包
开发语言·r语言
lbwxxc34 分钟前
go 基础
开发语言·后端·golang
-雷阵雨-36 分钟前
数据结构——栈和队列(模拟实现)
java·开发语言·数据结构·intellij-idea
字节高级特工1 小时前
网络协议分层与Socket编程详解
linux·服务器·开发语言·网络·c++·人工智能·php
祈祷苍天赐我java之术1 小时前
Redis 热点数据与冷数据解析
java·redis·mybatis
大飞pkz1 小时前
【设计模式】访问者模式
开发语言·设计模式·c#·访问者模式
9号达人1 小时前
Java20 新特性详解与实践
java·后端·面试