ass*_*ias 4 java java-8 java-stream
如果s下面的流至少包含n元素,那么流sLimit可能具有少于n元素的情况是什么?
Stream sLimit = s.limit(n);
Run Code Online (Sandbox Code Playgroud)
问题的原因:在这个答案中,我读到:
尽管有外观,但使用
limit(10)并不一定会产生一个只SIZED包含10个元素的流 - 它可能会少一些.
你误解了这个陈述.如果Stream至少包含n元素并且您limit(n)在其上调用它,它将具有确切的n元素,但Stream 实现可能不会意识到它,因此具有不太理想的性能.
相比之下,某些Stream源Spliterator确定它们具有固定的大小,例如在创建Stream阵列或IntStream通道时IntStream.range.他们可以优化比一个更好Stream用limit(n).
创建parallel Streamvia时Stream.generate(MyClass::new).limit(10),仍将按顺序调用构造函数,并且只能并行运行后续操作.相反,在使用时IntStream.range(0, n).mapToObj(i -> new MyClass()),整个Stream操作(包括构造函数调用)可以并行运行.
我认为Holger和Sotirios的答案是准确的,但因为我是发表声明的人,我想我应该自己解释一下.
我主要谈论的是分裂器特性,特别是SIZED特性.这基本上是关于流阶段的"静态"信息,这些信息在流水线设置时已知,但在流实际执行之前.实际上,它用于确定流的执行策略,因此必须在流执行之前知道它.
该limit()操作创建了一个包裹其上游分裂器的分裂器,因此limit分裂器需要确定要返回的特征.即使它的上游分裂器是SIZED,它也不知道确切的大小,因此必须关闭该SIZED特性.
所以如果你是程序员,那就写:
IntStream.range(0, 100).limit(10)
Run Code Online (Sandbox Code Playgroud)
你当然会说这个流有10个元素.(而且它会.)但是由此产生的分裂者仍然没有SIZED.毕竟,limit运营商不知道上述与此之间的区别:
IntStream.range(0, 1).limit(10)
Run Code Online (Sandbox Code Playgroud)
至少在分裂器特性方面.
所以这就是为什么,即使有时它似乎应该如此,limit操作员也不会返回已知大小的流.这又会影响分裂策略,从而影响并行效率.
| 归档时间: |
|
| 查看次数: |
220 次 |
| 最近记录: |