java - 在单个 lambda 表达式中将元素添加到不同的集合

标签 java lambda java-8

我可能使用了错误的术语,请随时纠正。

我有一个采用Runnable 的测试方法:

void expectRollback(Runnable r) { .. }

我可以这样调用这个方法:

expectRollback(() -> aList.add(x))

太棒了,我了解 lambda!这太棒了。让我们变得 super 聪明......

expectRollback(() -> aList.add(x) && bList.add(y))

但是什么?那不会编译:'void' 方法不能返回值。 难道第一次调用也没有返回值吗?第一次调用和第二次调用有什么区别?

最佳答案

这很微妙,但我想我明白了。

JLS 15.27.3我们有:

A lambda expression is congruent with a function type if all of the following are true:

  • ...
  • If the lambda parameters are assumed to have the same types as the function type's parameter types, then:
    • If the function type's result is void, the lambda body is either a statement expression (§14.8) or a void-compatible block.
    • ...
  • ...

现在 aList.add(x) 是一个语句表达式,但是 aList.add(x) && bList.add(y) 不是。您可以看到没有涉及任何 lambda 表达式 - 只需尝试将它们用作语句:

aList.add(x); // Fine
aList.add(x) && bList.add(y); // Error: "not a statement"

如果将该表达式包装在方法调用中,那很好,因为方法调用又是一个语句表达式:

rollback(() -> Boolean.valueOf(aList.add(x) && bList.add(y)));

我实际上并不是建议您这样做 - 只是试图解释为什么这样做会奏效,但您之前的尝试却没有奏效。

如果我们假设 List.add 确实每次都会返回 true,只要使用 block lambda:

rollback(() -> { aList.add(x); bList.add(y); });

无论如何,我认为这更清楚,因为它更明显地表明您关心第一个 add 调用返回的值。

关于java - 在单个 lambda 表达式中将元素添加到不同的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46510505/

相关文章:

java流找到匹配还是最后一个?

java - 最有效地从文件中写入和读取 LocalDateTime

java - 单击 TextView 后 Android 应用程序停止工作

java - IntelliJ 中生成代码的源代码级调试

c++ - 标准是否保证无捕获 lambda 为空?

regex - 提取除第一个单词之外的所有单词的第一个字符

java - java8中的流切割

java - 在Java上的Redis Hash中列出

java - JFace 对话框以编程方式最大化

c# - 未应用自定义 lambda 表达式