我目前正在解决在Java8中使用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函数通常执行短路操作(一旦检测到错误条目,“循环”就会中断并返回错误结果)。
到目前为止,我最好的解决方案是使用map/filter/count组合:
return entries
.stream()
.map(entry -> entry.doComplexAction())
.filter(result -> result == false)
.count() > 0
有没有更聪明/更干净的方法呢?
谢谢!
发布于 2017-02-16 20:39:43
它不应该看起来像这样:
boolean areAllSuccessful = entries.stream()
.map(entry -> entry.isSuccessful())
.reduce(Boolean.TRUE, Boolean::logicalAnd);
发布于 2017-02-16 23:07:02
最整洁、最有效的方法是在allMatch()
中使用方法引用
return entries.stream().allMatch(SomeEntry::isSuccessful);
如果您有1000个元素,请考虑使用parallelStream()
。
这不会处理每个元素(它在第一个false
返回),所以如果您的isSuccessful()
方法有副作用,那么它就是一个坏名字,您应该重命名它或重构代码以在process()
(或类似的)方法中执行副作用,并让isSuccessful()
返回结果,如果process()
没有被第一次调用,则抛出IllegalStateException
。
如果你不重构,一些开发人员(包括你)会调用isSuccessful()
而没有意识到它“做了些什么”,这可能是不好的。
发布于 2017-02-16 20:17:57
如果您要使用count()
,那么实际上并不需要map()
return !(entries
.stream()
.filter(entry -> !entry.isSuccessful())
.count() > 0);
如果isSuccessful()
方法没有副作用,您只需要知道是否所有条目都成功,就可以使用allMatch()
return entries
.stream()
.allMatch(entry -> entry.isSuccessful());
这确实是一个短路操作,一旦找到isSuccessful()
为false
的条目,它就会返回false
,除非必要,否则不会消耗整个流。但是您已经评论过,isSuccesful()
实际上意味着“执行一些复杂的操作,然后告诉我它们是否成功”,所以它不适用。
https://stackoverflow.com/questions/42273590
复制相似问题