Java 8 Lambdas - 按位和操作

时间:2017-02-16 12:11:15

标签: java for-loop lambda java-8 bitwise-operators

我目前正在解决使用Java 8中的Lambdas使用按位运算的for循环转换问题。

给定一组复杂的条目,循环需要遍历所有条目并在它们上调用给定的方法(方法返回布尔值)。然后,返回结果。

换句话说,我需要在所有条目上调用该方法并存储结果。 背后的原因是每个条目独立执行复杂的操作,必须执行。最终结果是结果的组合。

代码段:

boolean areAllSuccessful = true;
for (SomeEntry entry : entries) {
     areAllSuccessful = areAllSuccessful & entry.doComplexAction(); // keep calling the method on other entries regardless of the result.
}

return areAllSuccessful;

问题在于Java 8中的Lambda函数通常执行短路操作(一旦检测到错误条目,“循环”中断并返回错误结果)。

到目前为止,我最好的解决方案是使用地图/过滤器/计数组合:

return entries
       .stream()
       .map(entry -> entry.doComplexAction())
       .filter(result -> result == false)
       .count() > 0

有更智能/更清洁的方法吗?

谢谢!

3 个答案:

答案 0 :(得分:28)

不应该看起来像这样:

boolean areAllSuccessful = entries.stream()
   .map(entry -> entry.isSuccessful())
   .reduce(Boolean.TRUE, Boolean::logicalAnd);

答案 1 :(得分:19)

最新,最有效的方法是使用allMatch()

的方法引用
return entries.stream().allMatch(SomeEntry::isSuccessful);

如果您有1000个元素,请考虑改为使用parallelStream()

这不处理每个元素(它在第一个false返回),所以如果你的isSuccessful()方法有副作用,那就是一个坏名字,你应该重命名它或重构代码到在process()(或类似)方法中执行副作用,并isSuccessful()返回结果,如果IllegalStateException尚未首次调用,则抛出process()

如果你没有重构,一些开发人员(包括你)会在没有意识到“做东西”的情况下致电isSuccessful(),这可能是坏事。

答案 2 :(得分:11)

如果您要使用map(),那么您真的不需要count()

return !(entries
        .stream()
        .filter(entry -> !entry.isSuccessful())
        .count() > 0);

如果方法isSuccessful()没有副作用,而您需要知道的是,如果所有条目都成功,您可以使用{{1} }:

allMatch()

这确实是一个短路操作,一旦找到return entries .stream() .allMatch(entry -> entry.isSuccessful()); false的条目,就会返回isSuccessful(),除非必要,否则不会消耗整个流。但是你已经评论说false真的意味着"做一些复杂的动作然后然后告诉我它们是否成功",所以它不适用。