Lambda 表达式核心是“参数 → 行为”映射,需匹配函数式接口;左侧按参数数量写()、s或(a,b),类型可省略;右侧依返回类型写表达式或带return的语句块;仅适用于@FunctionalInterface,且逻辑应简洁明确。

掌握 Lambda 表达式的箭头语法,核心在于理解“参数 → 行为”的映射关系,而不是死记语法格式。它不是新功能,而是把原本要写几行的逻辑,压缩成一行可传递、可复用的代码片段。
看清左侧:参数怎么写才对
左侧括号里是函数式接口抽象方法的参数,类型通常可省略,JVM 能自动推断:
- 无参写 (),比如启动线程:
() -> System.out.println("run") - 单参可省括号,如遍历字符串:
s -> s.length() > 3 - 多参必须带括号和逗号:
(a, b) -> a.compareTo(b) - 需要显式类型时(少见但必要),写成 (String s, int n),尤其在类型模糊或重载方法调用时
写好右侧:表达式体不是随便堆代码
右侧不是任意语句块,它必须匹配函数式接口抽象方法的返回类型和行为:
- 如果方法返回值是 void(如 Consumer.accept),右侧可以是语句,如
s -> System.out.print(s) - 如果方法有返回值(如 Function.apply),单表达式自动返回结果:
s -> s.toUpperCase() - 含多条语句必须加大括号 + return:
s -> { System.out.println(s); return s.trim(); } - 别在右侧写复杂逻辑——超过两行就该抽成方法,再用方法引用替代
找准接口:没有函数式接口,箭头就无效
Lambda 只能用于函数式接口(@FunctionalInterface 标注、仅一个抽象方法)。常见内置接口有:
-
Runnable:无参无返回 →
() -> doSomething() -
Consumer<T>:接收一个参数,不返回 →
user -> log(user.getName()) -
Function<T,R>:接收 T,返回 R →
str -> Integer.parseInt(str) -
Predicate<T>:接收 T,返回 boolean →
s -> s.startsWith("A")
自定义接口时,加 @FunctionalInterface 注解,编译器会帮你检查是否合规。
用对时机:什么时候该上 Lambda
不是所有地方都适合写箭头,关键看三点:
- 目标是传递行为:比如排序规则、过滤条件、事件响应、线程任务
- 逻辑足够简单:一眼能看出“输入→输出”或“做什么”,不绕弯
- 上下文已有明确函数式接口:如 stream().filter(...)、button.setOnAction(...)、Collections.sort(..., ...)
- 避免嵌套:不要写
list.stream().map(x -> x.stream().filter(y -> y > 0).count())这类嵌套 Lambda,可读性差,调试困难
箭头语法本身很简单,难的是判断“这里到底适不适合用”。多从接口契约出发,少凭感觉写,业务代码自然就轻了、活了。

















