1. 基础语法入门
1.1. 规则
先用最直观的例子理解转化逻辑。
// 传统写法
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
}).start();
// Lambda写法
new Thread(() -> System.out.println("Hello")).start();规则总结:
Lambda 必须基于函数式接口(只有一个抽象方法的接口)
语法结构
(参数列表)-> {函数体}参数类型可以省略;函数体若只有一句可省略大括号和 return。
1.2. 示例
1.2.1. 无 Lambda 版本(老写法)
interface Demo {
void run(String name);
}
public class LambdaTest {
public static void main(String[] args) {
Demo d = new Demo() {
@Override
public void run(String name) {
System.out.println("Hello, " + name);
}
};
d.run("毛凯翔");
}
}
这段代码没问题,但很啰嗦 —— 创建匿名类、写接口名、重写方法。
1.2.2. 改成 Lambda 写法(带参数)
只要接口里只有一个方法,就可以用 Lambda 简写:
interface Demo {
void run(String name);
}
public class LambdaTest {
public static void main(String[] args) {
// 用Lambda写法,直接实现接口方法
Demo d = (name) -> {
System.out.println("Hello, " + name);
};
d.run("毛凯翔");
}
}
进一步简化(语法糖)
Demo d = name -> System.out.println("Hello, " + name);省了:
参数的小括号(因为只有一个参数)
花括号(因为只有一句话)
return(因为只有一行返回表达式)
1.2.3. 多参数的 Lambda 示例
比如写一个“计算器”:
interface Calculator {
int add(int a, int b);
}
public class LambdaTest {
public static void main(String[] args) {
Calculator c = (a, b) -> a + b;
int sum = c.add(5, 7);
System.out.println(sum); // 输出 12
}
}(a, b) 是参数列表,-> 后面是返回表达式。
1.2.4. 函数体有多行代码时
如果逻辑多于一行,必须加 {},并手动写 return:
interface Calculator {
int add(int a, int b);
}
public class LambdaTest {
public static void main(String[] args) {
Calculator c = (a, b) -> {
System.out.println("正在计算...");
return a + b;
};
System.out.println(c.add(3, 4));
}
}1.2.5. 带参数的实际使用场景:集合操作
import java.util.*;
public class LambdaTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("Tom", "Jerry", "Mao");
// forEach里每个元素都作为参数传入Lambda
list.forEach(name -> System.out.println("Hello, " + name));
}
}在这里:
forEach会遍历每个元素;每次都会把元素作为参数传给
(name);于是执行
System.out.println(...)。
1.2.6. 带返回值的集合操作
import java.util.*;
import java.util.stream.Collectors;
public class LambdaTest {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 用Lambda转换每个元素
List<Integer> doubled = numbers.stream()
.map(x -> x * 2) // 带参数x,返回 x*2
.collect(Collectors.toList());
System.out.println(doubled); // [2, 4, 6, 8, 10]
}
}1.2.7. 加深理解
Lambda 永远不会自己执行(重点):
示例 1 ~ 4 中,lambda 表达式都不会执行,相当于只是定义了方法,并没被调用。需要在后面手动调用一句。但示例 5 ~ 6 中,集合里写的 lambda 表达式可以直接执行,为什么?
因为集合调用了它。
看一个 forEach 示例
List<String> list = Arrays.asList("Tom", "Jerry", "Mao");
list.forEach(name -> System.out.println("Hello " + name));你以为 Lambda 自动执行了?其实不是,forEach 内部写了循环代码,会主动去调用这个 Lambda。
展开看底层逻辑(伪代码)
forEach 方法的真实实现差不多像这样👇
public void forEach(Consumer<? super T> action) {
for (T t : this) {
action.accept(t); // 这里才是执行 Lambda 的地方
}
}所以当你写:
list.forEach(name -> System.out.println("Hello " + name));时其实等价于:
Consumer<String> action = (name) -> System.out.println("Hello " + name);
for (String t : list) {
action.accept(t); // 每个元素执行一次 Lambda
}✅ Lambda 并不是“自动运行”,而是被 forEach 这种方法主动调用了。
评论