在我的程序中,我会反复地收集Java 8 流,以将一个对象集合缩减为单个对象。该集合的大小在执行过程中可能会有很大的变化:从3个对象到几百个对象不等。
在优化代码和寻找瓶颈的过程中,我将流parallel。当时这样做是有效的,因为集合都相当大。后来,在更改程序的其他部分和参数后,集合变得更小了。我意识到,不让流并行更有效。这是有道理的:为4个对象分配工作到多个线程的开销太大了。然而,对于数百个对象,这是值得的。
如果我只能使大型流并行,那将非常方便:
当流是从数组, 集合或手动创建时,可以手动执行此操作。也就是说,我们知道哪些元素进入流中,因此可以跟踪这些元素。然而,我有兴趣以通用的方式解决这个问题,以便无论传递给
像
我很清楚流被设计成没有固定大小,特别是:
可能是无界的。虽然集合具有有限大小,但流不需要。短路操作,如
public void findInterestingFoo(Stream<Foo> foos) {
internalState.update(foos.collect(customCollector()));
}
在优化代码和寻找瓶颈的过程中,我将流parallel。当时这样做是有效的,因为集合都相当大。后来,在更改程序的其他部分和参数后,集合变得更小了。我意识到,不让流并行更有效。这是有道理的:为4个对象分配工作到多个线程的开销太大了。然而,对于数百个对象,这是值得的。
如果我只能使大型流并行,那将非常方便:
public void findInterestingFoo(Stream<Foo> foos) {
if (isSmall(foos)) {
internalState.update(foos.collect(customCollector()));
} else {
internalState.update(foos.parallel().collect(customCollector()));
}
}
当流是从数组, 集合或手动创建时,可以手动执行此操作。也就是说,我们知道哪些元素进入流中,因此可以跟踪这些元素。然而,我有兴趣以通用的方式解决这个问题,以便无论传递给
findInterestingFoo
的流是什么类型,都可以适当地处理并尽可能高效地处理。像
count()
这样的东西可能会有所帮助,但它会在我collect之前终止流。我很清楚流被设计成没有固定大小,特别是:
可能是无界的。虽然集合具有有限大小,但流不需要。短路操作,如
limit(n)
或findFirst()
,可以使对无限流的计算在有限时间内完成。 — java.util.stream
包描述
尽管如此,我想知道是否有任何方法可以在执行任何操作之前确定流中有多少元素。流真的不知道它是从一个有限的集合创建的吗?
Stream
并不知道它是否来自(无)限源,因为它既没有定义isFinite()
方法也没有定义size()
方法。 - Turing85SizedStream
接口或类似的东西。难道有吗?据我所知,由Arrays.stream
创建的流只是Stream
。 - Just a studentStream
接口中不可能"是我问题的完全可以接受的答案,我只是希望存在更好的方法 :-) - Just a student