gpt4 book ai didi

Java 8 : stop reduction operation from examining all Stream elements

转载 作者:太空狗 更新时间:2023-10-29 22:34:08 24 4
gpt4 key购买 nike

我想了解是否有一种方法可以在不检查整个流的情况下终止缩减操作,但我想不出办法。

用例大致如下:假设有一长串 Integer 需要折叠到一个 Accumulator 中。每个元素检查都可能很昂贵,因此在 Accumulator 中,我对传入的 Accumulator 执行检查以查看我们是否需要执行昂贵的操作 - 如果我们不需要,然后我简单地返回累加器。

对于小型(呃)列表来说,这显然是一个很好的解决方案,但大型列表会产生不必要的流元素访问成本,我想避免。

这是一个代码草图 - 仅假设串行缩减。

class Accumulator {
private final Set<A> setA = new HashSet<>;
private final Set<B> setB = new HashSet<>;
}

class ResultSupplier implements Supplier<Result> {

private final List<Integer> ids;

@Override
public Result get() {
Accumulator acc = ids.stream().reduce(new Accumulator(), f(), (x, y) -> null);

return (acc.setA.size > 1) ? Result.invalid() : Result.valid(acc.setB);
}

private static BiFunction<Accumulator, Integer, Accumulator> f() {
return (acc, element) -> {
if (acc.setA.size() <= 1) {
// perform expensive ops and accumulate results
}
return acc;
};
}
}

除了必须遍历整个 Stream 之外,还有一个我不喜欢的事实 - 我必须检查相同的条件两次(即 setA 大小检查)。

我考虑过 map()collect() 操作,但它们看起来更像是相同的,并没有发现它们实质上改变了我只是不检查整个流就无法完成折叠操作。

此外,我的想法是虚构的 takeWhile(p : (A) => boolean) Stream API 通讯器也不会给我们带来任何好处,因为终止条件取决于累加器,而不是每个流元素se.

请记住,我是 FP 的新手,所以 - 有没有办法让这项工作如我所料?我是否错误地设置了整个问题,或者这种限制是设计使然?

最佳答案

而不是以ids.stream()开头你可以

  1. 使用ids.spliterator()
  2. 将生成的拆分器包装到具有可变 boolean 标志的自定义拆分器中
  3. 拥有自定义拆分器的 tryAdvance如果标志被更改,则返回 false
  4. 使用 StreamSupport.stream(Spliterator<T>, boolean) 将您的自定义拆分器转换为流
  5. 像以前一样继续流水线
  6. 当你的累加器已满时,通过切换 boolean 值来关闭流

添加一些静态辅助方法以保持其功能。

生成的 API 可能与此有关

Accumulator acc = terminateableStream(ids, (stream, terminator) ->
stream.reduce(new Accumulator(terminator), f(), (x, y) -> null));

Additionally, my thinking is that imaginary takeWhile(p : (A) => boolean) Stream API correspondent would also buy us nothing

如果条件取决于累加器状态而不是流成员,它确实有效。这基本上就是我在上面概述的方法。

它可能会在 takeWhile 中被禁止由 JDK 提供,但使用拆分器的自定义实现可以自由采用有状态方法。

关于Java 8 : stop reduction operation from examining all Stream elements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30740709/

24 4 0