我可能使用了错误的术语,请随时纠正。
我有一个采用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/