K E*_*son 2 java lambda java-8 method-reference
当使用Java 8流时,我经常发现我需要重构一个多语句lambda表达式.我将用一个简单的例子来说明这一点.假设我已经开始编写这段代码:
Stream.of(1, 3).map(i -> {
if (i == 1) {
return "I";
} else if (i == 3) {
return "E";
}
return "";
}).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
现在我不太喜欢map通话中的大型lambda表达式.因此,我想把它重构出来.我看到两个选项,要么我Function在我的班级中创建一个实例:
private static Function<Integer, String> mapper = i -> {
if (i == 1) {
return "I";
} else if (i == 3) {
return "E";
}
return "";
};
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
Stream.of(1, 3).map(mapper).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
或者我只是制作一个方法:
private static String map(Integer i) {
if (i == 1) {
return "I";
} else if (i == 3) {
return "E";
}
return "";
}
Run Code Online (Sandbox Code Playgroud)
并使用方法参考:
Stream.of(1, 3).map(Test::map).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
除了明显的味道问题外,这两种方法都有任何优点或缺点吗?
例如,我知道堆栈跟踪在方法参考案例中变得更具可读性,这是一个小优势.
除非有一些我不知道的额外魔法,否则当前的lambda实现会将你的非捕获lambda变为静态方法,并将缓存lambda实例.通过明确地执行相同的操作(static final对lambda 的引用),您基本上复制了隐式工作,因此您最终会得到两个对同一事物的缓存引用.你也在打败lambda实例的延迟初始化,否则你将获得免费的.
这就是为什么我更喜欢方法参考:它更简单,更惯用,而且在实现方面似乎也更轻巧.
将多行lambda表达式重构为普通方法并在流中使用方法引用的一些原因是可维护性和可测试性.
当非平凡映射器函数变为普通方法时,它获取一个名称,它可用于单元测试框架.您可以轻松编写直接调用它的测试,并在必要时将其删除.
该方法还可以包含与之关联的文档注释,包括参数和返回值的文档.
如果映射器函数很复杂,这两个都非常有用.
将lambda表达式赋给字段并没有错,但我认为这样做的主要原因是如果字段在运行时被修改,例如,当应用程序的状态发生变化时.即使在这些情况下,我也可以考虑编写普通方法,然后使用方法引用而不是多行lambda表达式来分配字段.
使用字段的一个缺点是它要求您明确声明功能接口的泛型类型参数.IDE可以帮助解决这个问题,但它会增加程序的混乱.
我猜想使用方法引用的普通方法总是优于使用用lambda表达式初始化的final字段.
| 归档时间: |
|
| 查看次数: |
309 次 |
| 最近记录: |