Java Lambda 表达式 & Java Method Reference
Published on Nov 25, 2025, with 2 view(s) and 0 comment(s)
Ai 摘要:Java Lambda表达式是Java 8引入的语法糖,用于简化函数式接口(仅含一个抽象方法的接口)的匿名内部类写法。其基本格式为`(参数) -> {方法体}`,并能根据规则省略参数类型、括号及return等关键字。Lambda广泛应用于简化Runnable、Comparator等接口,并与Stream API结合进行集合操作,使代码更简洁。

🐑 什么是 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>Tvoid消费型接口(接受一个参数)
Function<T,R>TR转换型(map 等)
Predicate<T>Tboolean断言型(filter 用)
Runnablevoid无参,无返回
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::method

4️⃣ 构造器引用(构造方法)

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 类名()