Lambda 表达式怎么用

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

🧩 一、基本语法

几种常见写法:

场景 Lambda 写法 说明
无参无返回 () -> System.out.println("Hello") 最简形式
一个参数 (x) -> x * 2x -> 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 }

复制代码
(参数列表) -> { 函数体 }
相关推荐
小小龙学IT几秒前
Go 后端开发中的并发模式:从 Goroutine 到 Pipeline 实战
开发语言·后端·golang
小短腿的代码世界2 分钟前
Qt文本布局引擎深度解析:从QTextDocument排版到渲染的完整架构
开发语言·qt·架构
Leweslyh4 分钟前
《3GPP TS 28.312 面向移动网络的意图驱动管理服务》完整自学教程
开发语言·网络·php
2501_930707786 分钟前
使用 C# 在 Excel 中合并并居中单元格
开发语言·c#·excel
番茄去哪了8 分钟前
一篇文章讲懂SDN
java·spring
aidou13148 分钟前
Kotlin中自定义RadioGroup实现多个RadioButton自动换行
android·开发语言·kotlin·shape·radiobutton·selector·radiogroup
小短腿的代码世界9 分钟前
Qt Firebase集成深度解析:移动与嵌入式云后端解决方案
开发语言·qt
cici1587411 分钟前
基于Matlab的数字全息相位展开及再现实现
开发语言·matlab
AC赳赳老秦13 分钟前
OpenClaw + 华为云自动化:批量管理云资源、生成月度云账单分析与成本优化报告
java·开发语言·javascript·人工智能·python·mysql·openclaw
Irissgwe16 分钟前
C++ STL 详解:list 的介绍使用与模拟实现
开发语言·c++·stl·list