Java 8 个 Lambdas - 按位与运算

Java 8 Lambdas - Bitwise AND Operations

我目前正在处理在 Java 8 中使用 Lambda 进行按位运算的循环转换问题。

给定一组复杂条目,循环需要遍历所有条目并对它们调用给定方法(方法 returns 布尔值)。之后,return结果。

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

代码片段:

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 Functions通常会执行短路操作(一旦检测到错误输入,"loop"就会中断,错误结果是return编)。

到目前为止,我最好的解决方案是使用 map/filter/count 组合:

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

是否有 smarter/cleaner 方法来做到这一点?

谢谢!

如果您要使用 count():

,您实际上并不需要 map()
return !(entries
        .stream()
        .filter(entry -> !entry.isSuccessful())
        .count() > 0);

如果方法isSuccessful()没有side-effects,你需要知道的是如果所有条目都成功,你可以使用 allMatch():

return entries
        .stream()
        .allMatch(entry -> entry.isSuccessful());

这确实是一个 short-circuit 操作,一旦找到 isSuccessful()false 的条目,它将 return false,而不消耗除非必要,否则整个流。但是你已经评论说 isSuccesful() 真的意味着 "do some complex actions and then tell me if they were successful",所以它不适用。

不应该看起来像这样:

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

最简洁、最有效的方法是使用带有 allMatch()

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

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

这不会处理每个元素(它 return 在第一个 false 处),所以如果你的 isSuccessful() 方法有副作用,它是一个坏名字,你应该重命名它或重构代码以在 process() (或类似)方法中执行副作用并获得 isSuccessful() return 结果,抛出 IllegalStateException if process() 没有第一次被调用。

如果您不重构,一些开发人员(包括您)会在没有意识到的情况下调用 isSuccessful() "does stuff",这可能很糟糕。