方法引用

方法引用

方法引用是已有方法的简写形式。只有当 Lambda 的工作只是“把参数原样交给某个方法”时,才适合改成方法引用。

代码块JAVA · 2 行收起展开
Function<String, Integer> a = text -> Integer.parseInt(text);
Function<String, Integer> b = Integer::parseInt;

90cb70c802a2416ca8f5ad05b21c2604

四种形式

形式Lambda方法引用
静态方法x -> Integer.parseInt(x)Integer::parseInt
指定对象的实例方法x -> printer.print(x)printer::print
任意对象的实例方法x -> x.trim()String::trim
构造器x -> new User(x)User::new

1. 类名引用静态方法

代码块JAVA · 1 行收起展开
Function<String, Integer> parser = Integer::parseInt;

bcb9851e5b5245b0b008929080076085

2. 类名引用任意对象的实例方法

String::length 的接收者会成为函数的第一个参数。

代码块JAVA · 3 行收起展开
Function<String, Integer> length = String::length;
BiPredicate<String, String> startsWith = String::startsWith;
// 等价于 (text, prefix) -> text.startsWith(prefix)

b533d9f9ed7b4cf0abcd35c1d10ecc0b

08a8ee57ed0e48f0a74f4718dd73ca00

3. 对象引用实例方法

代码块JAVA · 2 行收起展开
PrintStream printer = System.out;
Consumer<String> output = printer::println;

643e918e70ea4cbdba85bc15afc5be15

4. 构造器引用

代码块JAVA · 3 行收起展开
Supplier<List<String>> listFactory = ArrayList::new;
Function<String, User> userFactory = User::new;
IntFunction<String[]> arrayFactory = String[]::new;

下面三张原课堂图保留为方法引用的补充对照:

44b92475f8b24a12a00325e1fa574d19

eb2f68f0002f446a9f256ef8b67aadf4

ef3ced8155014b0e800e1433056f35a7

在 Stream 中使用

代码块JAVA · 7 行收起展开
List<String> names = users.stream()
        .filter(User::active)
        .map(User::name)
        .map(String::trim)
        .toList();

names.forEach(System.out::println);

1626724aac934d0dbf98c178091a9249

判断是否适合使用

方法引用必须与目标函数式接口的参数和返回值兼容。若引用后难以看出接收者、参数顺序或业务意图,普通 Lambda 反而更清楚。

代码块JAVA · 2 行收起展开
// 这里 Lambda 比方法引用更能表达业务含义
orders.filter(order -> order.amount() >= minimumAmount);

延伸阅读