我在一本书(Fischer's Java Closures and Lambda,Apress 2015)中读到,方法引用比Lambda表达式更好。在我看来,对于使用其他语言的开发人员来说,lambda表达式更容易理解。那么为什么它说方法引用更可取呢?在Java8中编写lambda表达式是不好的做法吗?
在第2章的Lambda最佳实践部分,Fischer的书说:
尽可能使用方法引用而不是lambda。方法引用不仅更短,更容易阅读,而且使用方法引用将使您直接将方法视为值。这是你需要从代码库和大脑中删除的代码:
x -> it.do(x)
如果您很自然地编写了这些代码,那么您仍然没有跳到函数式编程的更高层次上思考。一旦您实现了这一飞跃,就会变得更容易与复杂的函数进行交流和工作,因为您将在类型中思考,而不是在值中思考。
it::do
List<String> list = ... ;
int[] lengths1 = list.stream().mapToInt(s -> s.length()).toArray();
int[] lengths2 = list.stream().mapToInt(String::length).toArray();
在本例中,lambda表达式的大小与方法引用的大小(以字符数为单位)大致相同。但是请注意,方法引用包含更多类型信息。它告诉读者元素类型是string
,这可能有助于理解长管道。如果编译器不能推断元素类型,那么它有时也会对编译器有所帮助,就像在复杂表达式中有时会发生的那样。
另一点是,使用方法引用通常会减轻您为一个形式参数命名的责任,该参数只是传递给另一个方法。命名通常很重要,但是lambda格式通常是“垃圾”名称,比如I
X
或S
,如本例所示。
方法引用的效率稍微高一点,因为它不需要生成一个必须通过调用才能到达string.length()方法的静态方法。但这种效率很少是一个重要的考虑因素。
(x, y) -> x + y
String::concat
Integer::sum
Double::sum
IntelliJ一直建议我用方法引用替换我的lambda表达式。 两者之间有什么客观差异吗?
我需要的算法,将检查是否给定的表达式是中缀,后缀或前缀表达式。我尝试了一种方法,通过检查字符串的第一个或最后两个项,例如。 AB如果字符串的第一个索引中有一个运算符,那么它就是一个前缀 AB如果字符串的最后一个索引中有一个运算符,那么它就是一个后缀 否则它就是一个中缀。 但是感觉不太合适,所以请建议我一个更好的算法。
6.4. 方法值和方法表达式 我们经常选择一个方法,并且在同一个表达式里执行,比如常见的p.Distance()形式,实际上将其分成两步来执行也是可能的。p.Distance叫作“选择器”,选择器会返回一个方法"值"->一个将方法(Point.Distance)绑定到特定接收器变量的函数。这个函数可以不通过指定其接收器即可被调用;即调用时不需要指定接收器(译注:因为已经在前文中指定过了),只要传入
问题内容: 假设我有一个通用接口: 和方法sort: 我可以调用此方法并将lambda表达式作为参数传递: 那会很好的。 但是现在,如果我将接口设为非泛型,并且将方法设为泛型: 然后像这样调用: 它不会编译。它在lambda表达式中显示错误: “目标方法是通用的” 好的,当我使用编译时,它显示以下错误: 从此错误消息看来,编译器似乎无法推断类型参数。是这样吗 如果是,那为什么会这样呢? 我尝试了各
我试图学习在Java8中使用lambda表达式的方法引用,但遇到了一些我无法完全理解的东西。 使用lambda表达式(而不是创建接口等),是否有更干净的方法来完成此操作?
问题内容: 在Python脚本中,我从调用了一个函数,但出现此错误: 这里到底出了什么问题? 问题答案: 不是有效的关键字参数名称。关键字参数必须是有效的标识符。您应该查看正在使用的库的文档,该参数的 实际 调用方式是–也许?