Lambda 表达式怎么用

Lambda 表达式是 Java 8 引入的一项重要特性,它提供了一种简洁的方式 来表示匿名函数(即没有名字的函数) ,常用于实现函数式接口(只有一个抽象方法的接口)。在 Java 中,Lambda 表达式主要用于简化回调、事件处理、集合操作等场景。

🧩 一、基本语法

几种常见写法:

场景 Lambda 写法 说明
无参无返回 () -> System.out.println("Hello") 最简形式
一个参数 (x) -> x * 2 或 x -> x * 2 单个参数可省略括号
多个参数 (x, y) -> x + y 必须加括号
多行语句 (x) -> { int r = x * 2; return r; } 需要大括号和 return
有返回值(单表达式) x -> x * 2 自动返回表达式结果

📌 二、使用前提:函数式接口

Lambda 只能用于函数式接口(Functional Interface),即:

  • 接口中有且仅有一个抽象方法
  • 可用 @FunctionalInterface 注解(非必须,但推荐)

常见内置函数式接口(都在 java.util.function 包中):

接口 方法 用途
Runnable void run() 无参无返回(如线程任务)
Consumer<T> void accept(T t) 消费一个参数,无返回
Supplier<T> T get() 无参,有返回
Function<T, R> R apply(T t) 有参有返回
Predicate<T> boolean test(T t) 判断条件(返回 boolean)

✅ 这些接口你不需要自己写,直接用!


🧪 三、实际例子

1. 线程启动(使用 Runnable)

复制代码
// 传统方式
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("老写法");
    }
}).start();

// Lambda 方式
new Thread(() -> System.out.println("Lambda 启动线程!")).start();

2. 集合遍历(使用 Consumer)

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

// 传统 for-each
for (String name : names) {
    System.out.println(name);
}

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

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

3. 过滤数据(使用 Predicate)

复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

// 找出偶数
List<Integer> evens = numbers.stream()
    .filter(n -> n % 2 == 0)   // Predicate<Integer>
    .collect(Collectors.toList());

System.out.println(evens); // [2, 4, 6]

4. 自定义回调

复制代码
@FunctionalInterface
interface Callback {
    void call(String message);
}

public static void doTask(Callback cb) {
    System.out.println("执行任务中...");
    cb.call("任务完成!");
}

// 调用
doTask(msg -> System.out.println("收到: " + msg));

5. 返回值(使用 Function)

复制代码
Function<String, Integer> strToInt = s -> Integer.parseInt(s);
int num = strToInt.apply("123");
System.out.println(num + 1); // 124

⚠️ 四、注意事项

  1. Lambda 不能单独存在,必须赋值给一个函数式接口类型。

    复制代码
    // ❌ 错误:不能这样写
    x -> x + 1;
    
    // ✅ 正确
    Function<Integer, Integer> f = x -> x + 1;
  2. 变量捕获(闭包):

    • Lambda 可以访问外部局部变量,但该变量必须是 effectively final(实际上不可变)

      int factor = 10; // 实际上 final(没被修改)
      Function<Integer, Integer> multiply = x -> x * factor;

  3. 不能修改外部局部变量:

    复制代码
    int count = 0;
    Runnable r = () -> count++; // ❌ 编译错误!

🔁 五、Lambda vs 匿名内部类

特性 匿名内部类 Lambda
语法 冗长 简洁
性能 每次创建新类 JVM 优化(可能复用)
适用范围 任意接口/抽象类 仅函数式接口
this 指向 匿名类实例 外部类实例

✅ 总结

Lambda 表达式让你用更少的代码做更多的事,尤其适合:

  • 回调函数
  • 集合流式操作(stream().map().filter().forEach())
  • 事件监听
  • 并发任务(如 ExecutorService.submit(() -> {...}))

💡 记住口诀:"左边参数,右边逻辑,中间箭头" → (params) -> { body }

复制代码
(参数列表) -> { 函数体 }
相关推荐
m0_587383007 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
·云扬·7 小时前
Prompt 工程与安全:从 System 设计到注入防御
java·人工智能·安全·ai·prompt
专注仿真7 小时前
引擎扩展性与集成设计深度剖析:从 14 个扩展点到 DIS→HLA 演进之路
开发语言·算法·仿真引擎·推演引擎
Best-Wishes7 小时前
科来网络分析系统(技术交流版)使用说明书
开发语言·junit·php
代码不停8 小时前
自动化测试(java)
java·开发语言·selenium·自动化
鬼手点金10 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
爱上网的小舟10 小时前
星际战士2启动错误怎么办?5种游戏报错解决方法
开发语言·php
paopaokaka_luck10 小时前
滑雪场管理系统(AI智能助手流式对话,ECharts 运营数据分析、教练、雪具与场地一体化预约,钱包支付退款、订单核销与服务评价)
java·人工智能·spring boot·网络协议·数据分析·echarts
阿里嘎多学长11 小时前
2026-10-12 GitHub 热点项目精选
开发语言·程序员·github·代码托管
Wang's Blog11 小时前
Java 项目实战: 交友项目 - Dubbo 的内部结构与一次调用的完整链路
java·dubbo