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 }

复制代码
(参数列表) -> { 函数体 }
相关推荐
washingtin1 分钟前
Get “https://registry-1.docker.io/v2/“: context deadline exceeded
java·开发语言
only-lucky7 分钟前
Python版本OpenCV
开发语言·python·opencv
三万棵雪松11 分钟前
【python-基础】
开发语言·python
一路往蓝-Anbo11 分钟前
C语言从句柄到对象 (七) —— 给对象加把锁:RTOS 环境下的并发安全
java·c语言·开发语言·stm32·单片机·嵌入式硬件·算法
先做个垃圾出来………12 分钟前
2610.转换二维数组
开发语言·python
利刃大大22 分钟前
【SpringBoot】validation参数校验 && JWT鉴权实现 && 加密/加盐
java·spring boot·jwt·加密
天下皆白_唯我独黑26 分钟前
php -S 启动项目访问路由报错处理
开发语言·php
清水迎朝阳27 分钟前
Qt 小白成长系列 1-- 官方 文本搜索示例解析
开发语言·qt
小北方城市网27 分钟前
第 3 课:前后端全栈联动核心 —— 接口规范 + AJAX + 跨域解决(打通前后端壁垒)
java·大数据·网络·python
Joe_Blue_0228 分钟前
Matlab入门案例介绍—常用的运算符及优先级
开发语言·数据结构·matlab·matlab基础入门案例介绍