《Effective Java》解读第43条:方法引用优先于Lambda
·
第43条:方法引用优先于Lambda
与匿名类相比,Lambda显然更加简洁,Java提供了比Lambda更加简洁的函数对象方法:方法引用。
方法引用通常比Lambda表达式更简洁、更直观,因此在大多数情况下应该优先使用方法引用。 但这不是绝对的,当Lambda表达式比方法引用更简洁时,应该使用Lambda。
方法引用
例如实现一个当这个键不在映射中时,将数字 和键关联起来;或者
当这个键 经存在,就负责递增该关联值的功能。
Lambda方法:
Map<String, Integer> map = new HashMap<>();
map.put("test", 1);
map.merge("test", 1, (oldValue, newValue) -> oldValue + newValue);
System.out.println(map.get("test")); // 2
方法引用:
idea通常也会提示可以替换。
map.merge("test", 1, Integer::sum);
对比发现,主要是两个参数没有添加太多价值,从代码上看,方法引用主要省去的就是参数和直接使用现成的实现方法。
你也可以自己写一个方法取实现,然后通过方法引用使用。
public class Main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("test", 1);
map.merge("test", 1, Main::mySum);
System.out.println(map.get("test")); // 2
}
public static int mySum(int a, int b) {
return a + b;
}
}
什么时候使用方法引用
当方法引用更加简洁时。
// 示例1:静态方法引用
// Lambda
list.stream().map(s -> Integer.parseInt(s))
// 方法引用
list.stream().map(Integer::parseInt)
// 示例2:实例方法引用
// Lambda
list.forEach(s -> System.out.println(s))
// 方法引用
list.forEach(System.out::println)
什么时候使用Lambda
当Lambda更简洁或更清晰时。
// 方法引用 - 过于冗长
service.execute(GoshThisClassNameIsHumongous::action);
// Lambda - 反而更简洁清晰
service.execute(() -> action());
// 方法引用 - 需要查看文档才知道是函数式接口方法
var list = new ArrayList<>();
list.stream().collect(Collectors.toCollection(ArrayList::new));
// Lambda - 更直观
list.stream().collect(Collectors.toCollection(() -> new ArrayList<>()));
五种方法引用
其中两个是有限制和无限制的实例方法引用在有限制的引用中,接收对象是在方法引用中指定有限制的引用本质上类似于静态引用:函数对象与被引用方法带有相同的参数 在无限制的引用中,接收对象是在运用函数对象时,通过在该方法的声明函数前面额外添加一个参数来指定的,无限制的引用经常用在流管道中作为映射和过滤函数。最后,还有两种构造器引用,分别针对类和数组,构造器引用是充当工厂对象
| 类型 | 语法 | 示例 | 等效 Lambda |
|---|---|---|---|
| 静态方法引用 | ClassName::staticMethod | Integer::parseInt | s -> Integer.parseInt(s) |
| 绑定实例方法引用 | instance::instanceMethod | System.out::println | s -> System.out.println(s) |
| 非绑定实例方法引用 | ClassName::instanceMethod | String::length | s -> s.length() |
| 类构造器引用 | ClassName::new | ArrayList::new | () -> new ArrayList() |
| 数组构造器引用 | Type[]::new | int[]::new | length -> new int[length] |
总结
总而言之,方法引用常常 Lambd 表达式更加简洁明了,只要方法引用更加简洁、清晰,就用方法引用;如果方法引用并不简洁,就坚持使用 Lambda。
更多推荐




所有评论(0)