Java Stream#limit返回的元素是否比预期的少?
如果下面的流Java Stream#limit返回的元素是否比预期的少?,java,java-8,java-stream,Java,Java 8,Java Stream,如果下面的流s至少包含n元素,那么流sLimit可能包含少于n元素(如果有)的情况是什么 Stream sLimit = s.limit(n); 提出问题的原因:在年,我读到: 尽管有这些外观,但使用limit(10)并不一定会产生一个大小正好为10个元素的size流——它可能只有更少的元素 你误解了这个说法。如果流至少有n个元素,并且您在其上调用limit(n),则它将正好有n个元素,但是流实现可能没有意识到它,因此性能不太理想 相反,某些流源(Spliterators)确实知道它们具有固
s
至少包含n
元素,那么流sLimit
可能包含少于n
元素(如果有)的情况是什么
Stream sLimit = s.limit(n);
提出问题的原因:在年,我读到: 尽管有这些外观,但使用
limit(10)
并不一定会产生一个大小正好为10个元素的size
流——它可能只有更少的元素
你误解了这个说法。如果
流
至少有n个
元素,并且您在其上调用limit(n)
,则它将正好有n个
元素,但是流
实现可能没有意识到它,因此性能不太理想
相反,某些流
源(Spliterator
s)确实知道它们具有固定的大小,例如,在创建或IntStream
via时。它们可以比具有限制(n)
的流更好地进行优化
当您通过Stream.generate(MyClass::new).limit(10)
创建并行流时,构造函数仍将按顺序调用,并且只能并行运行后续操作。相反,当使用IntStream.range(0,n).mapToObj(i->new MyClass())
时,整个Stream
操作,包括构造函数调用,都可以并行运行。我认为霍尔格和索蒂里奥斯的答案是准确的,但由于我是做出这一声明的人,我想我应该解释自己
我主要讲的是,特别是的大小
特性。这基本上是关于流阶段的“静态”信息,在管道设置时已知,但在流实际执行之前。实际上,它用于确定流的执行策略,因此在流执行之前必须知道它
limit()。即使其上游拆分器的大小为大小
,它也不知道确切的大小,因此必须关闭大小
特性
所以如果你,程序员,要写:
IntStream.range(0, 100).limit(10)
当然,您会说流正好有10个元素。(它会的。)但生成的拆分器仍然没有大小。毕竟,limit
操作符不知道上面和下面的区别:
IntStream.range(0, 1).limit(10)
至少在分离器特性方面
这就是为什么,即使有时它似乎应该返回,limit
操作符也不会返回已知大小的流。这反过来会影响拆分策略,从而影响并行效率。我认为Stuart的意思是从概念上讲的。与中一样,使用已知大小的流
比尝试从您不知道大小的流
获取N
更有意义。我认为如果原始的流至少有n
元素,那么limit(n)
就不可能返回一个n
元素少于n
的新流。哇,我离开了一个小时,你们都已经完成了。:-)@斯图尔特马克:我不是有意叫醒你的,但谢谢你的澄清:-)