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 或者回调事件中,减少了编写事件监听器的样板代码。
相关推荐
侠客行03177 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪7 小时前
深入浅出LangChain4J
java·langchain·llm
灰子学技术9 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
老毛肚9 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎10 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
二十雨辰10 小时前
[python]-AI大模型
开发语言·人工智能·python
Yvonne爱编码10 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚10 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂10 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
pas13610 小时前
41-parse的实现原理&有限状态机
开发语言·前端·javascript