英文:
Java: How to count and process elements in a Stream without auxiliary structures or peek()?
问题 {#heading}
我正在使用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 <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 -&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}
得分: 1
唯一可行的解决方案是处理你描述的情况,看起来像是
streamData.forEachOrdered(elem -> {
int i = totalCount.getAndIncrement();
if (i >= startPosition && i < startPosition + itemsPerPage) {
itemHandler.accept(i);
}
})
我不认为存在更好的解决方案;流并不是为你试图用它们做的事情而设计的。 英文:
The only viable solution that deals with the case you've described looks like
streamData.forEachOrdered(elem -> {
int i = totalCount.getAndIncrement();
if (i >= startPosition && i < 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.