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",这可能很糟糕。
我目前正在处理在 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",这可能很糟糕。