java stream sum()短路

enyaitl3  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(325)

这个问题在这里已经有答案了

如何在流上短路reduce()操作(3个答案)
两年前关门了。
在做一个我写了这行的项目时,它基本上是根据有多少子节点来决定是否合并当前节点。

int succNodes = Arrays.stream(children).mapToInt(PRQuadNode::count).sum();
if (succNodes <= bucketingParam) { /* do something */ }

问题是 succNodes 通常会比 bucketingParam . 如果我已经找到足够多的钱,就没有必要继续数了。如果我知道检查succnodes<=bucketingparam会失败,那么让流提前停止的最佳方法是什么?
注意:在这种情况下,儿童总是4号的。
注2:prquadnode::count是一个递归方法,它不是尾部递归的。

jxct1oxe

jxct1oxe1#

实际上,Java9附带了 takeWhile 方法,这是流的短路操作,返回与给定 predicate 匹配的元素的最长前缀。
因为 predicate 依赖于前面元素的总和,所以必须使用 Package 器来存储中间结果。在下面的示例中,我使用 AtomicInteger 班级:

AtomicInteger sum = new AtomicInteger();
Arrays.asList(2, 3, 5, 7, 11, 13, 17).stream()
    .takeWhile(i -> sum.addAndGet(i) < 15)
    .forEach(System.out::println);

退货:

2
3
5
des4xlb0

des4xlb02#

一个人不能这样做 stream . 但是,如果大于,则可以过滤掉 bucketingParam . 如果其中任何一个已经大于 bucketingParam 继续下去是没有意义的。

if (Arrays.stream(children).mapToInt(PRQuadNode::count)
                           .noneMatch(x -> x > bucketingParam)) {
    int succNodes = Arrays.stream(children).mapToInt(PRQuadNode::count).sum();
}
7jmck4yq

7jmck4yq3#

不能仅使用流来短路流管道。
一种解决方法(使用副作用)是:

int[] c = new int[1];
boolean r = Arrays.stream(children).noneMatch(e -> (c[0] = c[0] + e.count()) > bucketingParam);
if (r) { /* do something */ }

这完成了任务,但不幸的是,它不是线程安全的(怀疑你是否会并行运行它,因为你的源代码总是有4个元素)。
当务之急是:

int succNodes = 0;
boolean result = true;
for (PRQuadNode p : children) {
    if (succNodes > bucketingParam) {
         result = false;
         break;
    }
    succNodes += p.count();
}

if (result) { /* do something */ }

相关问题