我在一本书(Fischer的 Java Closures和Lambda ,Apress 2015)中读到,方法引用优于lambda表达式。从我的角度来看,使用其他语言的开发人员更容易理解lambda表达式。那为什么说方法参考更可取?在Java 8中编写lambda表达式是不好的做法吗?
答案 0 :(得分:18)
在第2章的 Lambda Best Practices 部分中,Fischer的书中说:
尽可能使用方法引用而不是lambda。方法引用不仅更短且更容易阅读,而且使用方法引用可以让您直接将方法视为值。这是您需要从代码库和大脑中删除的代码:
x -> it.do(x)
如果您自然地编写了该代码,那么您仍然没有在更高级别的函数式编程中进行思考。一旦实现了这一飞跃,沟通和处理复杂功能将变得更加容易,因为您将考虑类型,而不是价值观。
虽然我大多同意这个结论,但我不确定是否会购买费舍尔的推理线。方法引用通常(尽管不总是)比写出的lambda短。在第一部分中,他说方法参考将帮助您将方法视为值。好的,但后来他说事情会变得容易,因为你会在类型而不是价值观中思考。我不确定这意味着什么。
可以重写他给出的示例表达式
it::do
这肯定比原版短,但很难从一个小例子中概括出来。
这是我对方法参考与写出的lambdas的看法。
如果在使用lambda表达式和方法引用之间做出选择,那么通常优先考虑方法引用的情况。但这不是一个严格的规则,并且可能存在lambda表达式更可取的情况。这也是一种品味问题。
如果您熟悉其他语言的lambda表达式,那么Java中的lambda表达式可能比方法引用更加熟悉。但是,在您学习方法参考之前,我认为这是一个临时状态。一旦他们更熟悉,方法参考的优点可能超过最初的不熟悉。
考虑这个获取字符串长度的简单示例:
List<String> list = ... ;
int[] lengths1 = list.stream().mapToInt(s -> s.length()).toArray();
int[] lengths2 = list.stream().mapToInt(String::length).toArray();
在这种情况下,lambda表达式的大小与方法引用的大小(字符数)大致相同。但请注意,方法引用包含更多类型信息。它告诉读者元素类型是String
,这可能有助于理解长管道。如果编译器无法推断元素类型,它有时也会有所帮助,因为有时会出现在复杂的表达式中。
另一点是,使用方法引用通常会减轻您为正式参数提供名称的责任,该参数只是简单地传递给另一个方法。命名通常很重要,但lambda正式通常是&#34;垃圾&#34;像本例中的i
x
或s
这样的名称。
方法引用效率更高一些,因为它不需要生成必须通过调用来获取String.length()方法的静态方法。但这种效率很少是一个重要的考虑因素。
还要考虑这个例子,故意剥夺上下文:
(x, y) -> x + y
这是字符串连接还是数字加法?如果数字,什么类型?根据语言规则,这必须在编译时知道,否则它是一个错误。虽然编译器可能很清楚,但有时这对读者来说并不是很清楚。请考虑这些方法参考:
String::concat
Integer::sum
Double::sum
在这种情况下,使用操作名称可以使读者非常明白目的是什么。