🐑 什么是 Lambda?
Java Lambda(Java 8 引入)是一种 简化匿名内部类写法的函数形式表达式。
本质:
Lambda 只是“把一个接口中只有一个方法(函数式接口)”的写法变短了。
🎯 Lambda 必须依赖“函数式接口”
所谓函数式接口,就是 接口里只有一个抽象方法 的接口,例如:
- Runnable
- Comparator
- Callable
- 自定义:@FunctionalInterface
例子:
@FunctionalInterface
interface MyFunc {
void run();
}⚡ Lambda 的基本写法
(参数列表) -> { 方法体 }例如:
() -> System.out.println("Hello");🧩 例子 1:简化 Runnable
传统写法:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
}).start();Lambda:
new Thread(() -> System.out.println("Hello")).start();更简洁,一行搞定。
🧩 例子 2:带参数的 Lambda(Comparator)
传统写法:
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.length() - b.length();
}
});Lambda:
Collections.sort(list, (a, b) -> a.length() - b.length());⚙️ Lambda 的简化规则
✔ 1. 参数类型可省略
(a, b) -> a + b✔ 2. 单个参数可以省略括号
s -> s.toUpperCase()✔ 3. 方法体只有一句时,可省略 {} 和 return
() -> 123🔥 常见函数式接口(Java 内置)
| 接口 | 参数 | 返回 | 解释 |
| Supplier<T> | 无 | T | 供给型接口 |
| Consumer<T> | T | void | 消费型接口(接受一个参数) |
| Function<T,R> | T | R | 转换型(map 等) |
| Predicate<T> | T | boolean | 断言型(filter 用) |
| Runnable | 无 | void | 无参,无返回 |
| Comparator<T> | (T,T) | int | 比较两个对象 |
📦 实战案例(最常用)
① Stream + Lambda(最典型)
List<String> list = Arrays.asList("java", "python", "go");
list.stream()
.filter(s -> s.length() > 3)
.map(s -> s.toUpperCase())
.forEach(s -> System.out.println(s));② Lambda + 自定义函数式接口
@FunctionalInterface
interface Calc {
int add(int a, int b);
}
Calc c = (a, b) -> a + b;
System.out.println(c.add(1, 2)); // 3③ Lambda 用在按钮事件(JavaFX / Swing)
button.setOnAction(e -> System.out.println("Clicked"));🎯 为什么要用 Lambda?
- 代码更简洁
- 更符合函数式编程风格
- 配合 Stream API 极其强大
- 更少的匿名类写法
📌 快速记忆口诀
要用 Lambda → 必须是函数式接口(只有一个方法)
(参数) -> {逻辑}
参数 1 个 → () 可省略
逻辑 1 行 → {} 和 return 可省略
类型全不用写 → 自动推断🎯 Method Reference 是什么?
方法引用(Method Reference)是 Lambda 的进一步简化写法。
如果一个 Lambda:
(x) -> someObject.someMethod(x)只是在 调用一个已经存在的方法,那么你就可以写成方法引用。
⭐ 方法引用的四大类
Java Method Reference 有 4 种写法:
| 写法 | 说明 |
| 1. 对象::实例方法 | 使用一个已有的对象 |
| 2. 类::静态方法 | 调用类的静态方法 |
| 3. 类::实例方法 | 当 lambda 的第一个参数是调用者,第二参数是方法参数 |
| 4. 类名::new | 构造方法引用 |
下面给你一一例子说明 👇
1️⃣ 对象::实例方法
Object::instanceMethod
例如:
System.out::println等价于:
s -> System.out.println(s)用于:
list.forEach(System.out::println);2️⃣ 类::静态方法
Class::staticMethod
例如:
Integer::parseInt等价于:
s -> Integer.parseInt(s)用于:
Stream.of("1", "2", "3")
.map(Integer::parseInt)
.forEach(System.out::println);3️⃣ 类::实例方法
Class::instanceMethod
当 Lambda 第一个参数是方法调用者时:
(a, b) -> a.compareTo(b)可写成:
String::compareTo用于排序:
list.sort(String::compareTo);也用于 Stream:
list.stream()
.sorted(String::compareTo)
.forEach(System.out::println);本质:
x -> x.method(y)
变为
Class::method4️⃣ 构造器引用(构造方法)
Class::new
例如:
Supplier<List> creator = ArrayList::new;
List list = creator.get();等价于:
() -> new ArrayList()再比如:
Function<String, User> userCreator = User::new;
User user = userCreator.apply("Tom");等价于:
name -> new User(name)🧪 实战例子(最常用)
📌 示例 1:打印列表
list.forEach(System.out::println);📌 示例 2:字符串转大写
list.stream()
.map(String::toUpperCase)
.forEach(System.out::println);📌 示例 3:排序
list.stream()
.sorted(String::compareTo)
.forEach(System.out::println);📌 示例 4:对象列表按字段排序
users.stream()
.sorted(Comparator.comparing(User::getAge))
.forEach(System.out::println);这里 User::getAge 就是实例方法引用。
📌 示例 5:构造方法引用创建对象
Stream.of("Tom", "Jack", "Alice")
.map(User::new) // 调用 User(String name)
.forEach(System.out::println);🎯 总结口诀(超容易记)
方法引用,就是把 lambda 再简化。
对象::实例方法 等价于 x -> 对象.method(x)
类::静态方法 等价于 x -> Class.method(x)
类::实例方法 等价于 (a, b) -> a.method(b)
类名::new 等价于 () -> new 类名()