Lambda表达式或方法参考?

zaw*_*tut 10 java lambda java-8

我读了一本书(Fischer的Java Closures和Lambda,Apress 2015),方法引用比lambda表达更好.从我的角度来看,使用其他语言的开发人员更容易理解lambda表达式.那为什么说方法参考更可取?在Java 8中编写lambda表达式是不好的做法吗?

Stu*_*rks 19

在第2章的Lambda最佳实践部分中,Fischer的书中说:

尽可能使用方法引用而不是lambda.方法引用不仅更短且更容易阅读,而且使用方法引用可以让您直接将方法视为值.这是您需要从代码库和大脑中删除的代码:

    x -> it.do(x)
Run Code Online (Sandbox Code Playgroud)

如果您自然地编写了该代码,那么您仍然没有在更高级别的函数式编程中进行思考.一旦实现了这一飞跃,沟通和使用复杂功能将变得更加容易,因为您将考虑类型而不是值.

虽然我大多同意这个结论,但我不确定我是否会购买Fischer的推理线.方法引用通常(尽管不总是)比写出的lambda短.在第一部分中,他说方法参考将帮助您将方法视为值.好的,但后来他说事情会变得更容易,因为你会考虑类型,而不是价值观.我不确定这意味着什么.

可以重写他给出的示例表达式

    it::do
Run Code Online (Sandbox Code Playgroud)

这肯定比原版短,但很难从一个小例子中概括出来.

这是我对方法引用与写出的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();
Run Code Online (Sandbox Code Playgroud)

在这种情况下,lambda表达式的大小与方法引用的大小(字符数)大致相同.但请注意,方法引用包含更多类型信息.它告诉读者元素类型String,这可能有助于理解长管道.如果它无法推断元素类型,它有时对编译器也有帮助,因为有时会出现在复杂表达式中.

另一点是,使用方法引用通常会减轻您为正式参数提供名称的责任,该参数只是传递给另一个方法.命名往往是重要的,但拉姆达甲醛往往像"垃圾"的名称i x或者s如本例.

方法引用更有效,因为它不需要生成必须调用以获取String.length()方法的静态方法.但这种效率很少是一个重要的考虑因素.

还要考虑这个例子,故意剥离上下文:

(x, y) -> x + y
Run Code Online (Sandbox Code Playgroud)

这是字符串连接还是数字加法?如果数字,什么类型?根据语言规则,必须在编译时知道,否则这是一个错误.虽然编译器可能很清楚,但有时这对读者来说并不是很清楚.请考虑这些方法参考:

String::concat
Integer::sum
Double::sum
Run Code Online (Sandbox Code Playgroud)

在这种情况下使用操作的名称使得读者非常清楚预期的内容.