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 或者回调事件中,减少了编写事件监听器的样板代码。
相关推荐
爱吃南瓜的北瓜8 分钟前
Maven之jjwt依赖爆红
java·pycharm·maven
土豆儿@19 分钟前
java之泛型
java·开发语言
橘猫云计算机设计29 分钟前
基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!
java·数据库·spring boot·后端·python·计算机网络·毕设
m0_7482453444 分钟前
python——Django 框架
开发语言·python·django
曼巴UE51 小时前
UE5.3 C++ TArray系列(一)
开发语言·c++·ue5
熬夜苦读学习1 小时前
Linux文件系统
linux·运维·服务器·开发语言·后端
菜鸟一枚在这1 小时前
深度解析建造者模式:复杂对象构建的优雅之道
java·开发语言·算法
gyeolhada1 小时前
2025蓝桥杯JAVA编程题练习Day5
java·数据结构·算法·蓝桥杯
阿巴~阿巴~1 小时前
多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题
开发语言·数据结构·c++·算法·宽度优先
菜鸟一枚在这1 小时前
深入理解设计模式之代理模式
java·设计模式·代理模式