当前位置: 首页 > article >正文

【Java 新特性】深入浅出 Java Lambda 表达式

Java 8 的 Lambda 表达式是一次编程方式的革命,让代码更加简洁、高效。本文将从基础语法入手,逐步深入讲解 Lambda 表达式的常用用法、进阶场景以及开发中的实战案。


一、 什么是 Lambda 表达式?

Lambda 表达式是一种匿名函数,旨在减少冗长的代码。其核心在于将功能作为参数传递。

简单来说,它让代码从这样的写法:

new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello, Lambda!");
    }
};

变得简洁如斯:

() -> System.out.println("Hello, Lambda!");

二、Lambda 表达式的基础语法

Lambda 表达式的基本语法如下:

(parameters) -> expression
(parameters) -> { statements; }

1. 无参数,无返回值

() -> System.out.println("Hello, World!");
  • ():无参数
  • ->:表示 Lambda 的分隔符
  • System.out.println("Hello, World!")单行表达式作为 Lambda 体。

2. 有参数,无返回值

接收一个参数 x,并打印。

(x) -> System.out.println(x);

3. 有多个参数,有返回值

返回两个参数的和,省略了 {}return

(x, y) -> x + y

4. 多行代码

如果 Lambda 体有多行代码,必须用 {} 包裹,并显式使用 return 返回值:

(x, y) -> {
    int sum = x + y;
    System.out.println("Sum: " + sum);
    return sum;
}

三、Lambda 表达式的常用场景

场景 1:代替匿名内部类

Lambda 表达式常用于简化匿名类的实现。

传统写法

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Running...");
    }
};

Lambda 简化

Runnable runnable = () -> System.out.println("Running...");

场景 2:配合函数式接口

Lambda 表达式的核心是与 函数式接口 搭配使用。函数式接口是只包含一个抽象方法的接口,例如 java.util.function 包中的接口:

接口描述示例
Consumer<T>接收一个参数,无返回值x -> System.out.println(x)
Supplier<T>无参数,返回一个值() -> "Hello"
Function<T,R>接收一个参数,返回一个值x -> x.length()
Predicate<T>接收一个参数,返回布尔值x -> x > 0

示例:过滤集合

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
       .filter(x -> x % 2 == 0)  // 筛选偶数
       .forEach(System.out::println);

四、方法引用与构造器引用

Lambda 表达式的简化之道之一就是方法引用和构造器引用。

1. 方法引用

方法引用是 Lambda 表达式的一种简化形式,它通过 :: 运算符直接引用已有的方法。

类型示例说明
静态方法引用ClassName::staticMethodMath::max
实例方法引用instance::instanceMethodSystem.out::println
任意对象的方法引用ClassName::instanceMethodString::toUpperCase
构造器引用ClassName::newArrayList::new

示例:静态方法引用

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
numbers.forEach(System.out::println); // 等价于 x -> System.out.println(x)

示例:实例方法引用

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(String::toUpperCase); // 每个字符串转为大写

2. 构造器引用

通过构造器引用,可以动态创建对象实例。

示例:无参构造器

Supplier<List<String>> supplier = ArrayList::new;
List<String> list = supplier.get(); // 创建一个新的 ArrayList

示例:有参构造器

Function<String, Integer> converter = Integer::new;
Integer number = converter.apply("123"); // 将字符串 "123" 转为 Integer

五、开发中的实战案例

1. 集合排序

使用 Lambda 表达式快速排序:

List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
names.sort((a, b) -> a.compareTo(b)); // 按字典序排序

进一步简化为方法引用:

names.sort(String::compareTo);

2. 线程池任务

Lambda 在多线程中非常适合,尤其是简化任务提交:

ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> System.out.println("Task running in thread!"));

3. 文件操作

使用 Lambda 简化文件行处理:

Files.lines(Paths.get("data.txt"))
     .filter(line -> line.startsWith("Error")) // 筛选以 "Error" 开头的行
     .forEach(System.out::println);

六、总结表格

概念语法示例应用场景
Lambda 基本语法(x, y) -> x + y替代匿名类、简化代码
Consumer 接口x -> System.out.println(x)消费一个值,例如打印、保存
Supplier 接口() -> "Hello"提供一个值,例如默认值
Function 接口x -> x.length()转换一个值,例如字符串长度
Predicate 接口x -> x > 0判断条件,例如筛选集合
静态方法引用Math::max引用已有静态方法
实例方法引用System.out::println引用已有对象的方法
构造器引用ArrayList::new动态创建实例,例如 Supplier

http://www.kler.cn/a/460898.html

相关文章:

  • C++ hashtable
  • Oracle 23ai 图形界面安装
  • 关于 PPPOE技术的详细解释
  • HAL 库------中断相关函数
  • [Qt] 常用控件 | QWidget | “表白程序2.0”
  • 《机器学习》——线性回归模型
  • vim里搜索关键字
  • 【Windows】Windows系统查看目录中子目录占用空间大小
  • YK人工智能(二)——万字长文了解深度学习环境配置
  • grep如何打印行数
  • C++线程池的使用
  • 智能商业分析 Quick BI
  • Spring Security 3.0.2.3版本
  • 为什么需要设置 `NCCL_P2P_DISABLE=1` 和 `NCCL_IB_DISABLE=1`?
  • 4G报警器WT2003H-16S低功耗语音芯片方案开发-实时音频上传
  • 国产低代码框架zdppy开发笔记001 zdppy_api快速入门
  • 《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》学习笔记——HarmonyOS架构介绍
  • 力扣-数据结构-8【算法学习day.79】
  • 石岩路边理发好去处
  • Kerberos用户认证-数据安全-简单了解-230403
  • 二十三种设计模式-工厂方法模式
  • 【UE5】UnrealEngine源码构建1:tag为5.3.2源码clone
  • 与你共度的烟火日常
  • 开源即时通讯IM框架MobileIMSDK的鸿蒙NEXT端开发快速入门
  • 使用 `@Async` 实现 Spring Boot 异步编程
  • 打造多元化服务体系,拉卡拉助力传统商家提升数字化经营效能