Java:如何在不使用辅助结构或peek()的情况下计数和处理流中的元素?

huangapple go评论247阅读模式
英文:

Java: How to count and process elements in a Stream without auxiliary structures or peek()?

问题

我正在使用Java流并且我需要一个方法来同时计算流中的所有元素并在子集上执行skip()和limit()操作
我希望这样做而不使用任何辅助结构来减少堆空间使用因为输入的数据可能非常大

我也更愿意避免使用peek()方法因为在特定情况下可能会产生副作用如这篇[文章](https://4comprehension.com/idiomatic-peeking/)中详细说明的那样。

public static <T> long extractAndProcess(Stream<T> streamData, int pageIndex, int itemsPerPage, Consumer<T> itemHandler) {

    long startPosition = (long) pageIndex * itemsPerPage;
    AtomicLong totalCount = new AtomicLong();

    streamData.peek(item -> totalCount.incrementAndGet())
              .skip(startPosition)
              .limit(itemsPerPage)
              .forEachOrdered(itemHandler);

    return totalCount.get();
}
我尝试在这里使用peek()但与.limit()结合使用时它在特定情况下不起作用与我所假设的不同
英文:

I'm working with Java streams and I need a method to both count all elements in the stream and, at the same time, perform operations on a subset of them using skip() and limit().
I'm aiming to do this without using any auxiliary structures to reduce heap space usage, because the data entered can be very large.

I'd also prefer to steer clear of the peek() method due to its potential side effects in specific scenarios, as detailed in this article

public static &lt;T&gt; long extractAndProcess(Stream&lt;T&gt; streamData, int pageIndex, int itemsPerPage,   Consumer&lt;T&gt; itemHandler) {

    long startPosition = (long) pageIndex * itemsPerPage;
    AtomicLong totalCount = new AtomicLong();

    streamData.peek(item -&gt; totalCount.incrementAndGet())
              .skip(startPosition)
              .limit(itemsPerPage)
              .forEachOrdered(itemHandler);

    return totalCount.get();
}

I tried to use peek() here, but in combination with .limit() it doesn't work as I assumed in the specific cases.

答案1

得分: 1

唯一可行的解决方案是处理你描述的情况,看起来像是

streamData.forEachOrdered(elem -&gt; {
  int i = totalCount.getAndIncrement();
  if (i &gt;= startPosition &amp;&amp; i &lt; startPosition + itemsPerPage) {
    itemHandler.accept(i);
  }
})

我不认为存在更好的解决方案;流并不是为你试图用它们做的事情而设计的。

英文:

The only viable solution that deals with the case you've described looks like

streamData.forEachOrdered(elem -&gt; {
  int i = totalCount.getAndIncrement();
  if (i &gt;= startPosition &amp;&amp; i &lt; startPosition + itemsPerPage) {
    itemHandler.accept(i);
  }
})

I don't believe a better solution exists; streams are really not designed to do what you're trying to do with them.

huangapple
  • 本文由 发表于 2023年8月11日 02:22:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878399.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定