标准集合返回的Stream实现有多专业?

aio*_*obe 11 java java-8 java-stream

Stream是一个接口,所以每当有人抓住一个Stream对象时,隐藏了许多特定于实现的细节.

例如,请使用以下代码:

List<String> list = new ArrayList<>();
...
int size = list.stream()
               .count();
Run Code Online (Sandbox Code Playgroud)

它是在恒定时间还是线性时间运行?或这个:

Set<String> set = new TreeSet<>();
...
set.stream()
   .sorted()
   .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

那是O(n)还是O(n log n)?

一般来说,标准集合返回的流实现有多专业?

Bri*_*etz 15

它是在恒定时间还是线性时间运行?

当前实现以线性时间运行:

public final long count() {
    return mapToLong(e -> 1L).sum();
}
Run Code Online (Sandbox Code Playgroud)

但是,在某些情况下,可以在不变的时间运行(在某处可以使用RFE).

怎么样?流由流源,零个或多个中间操作以及终端操作(这里count()是终端操作)描述.流实现维护有关源的一组特征,并知道操作如何修改特征.例如,由Collection支持的流具有该特征SIZED,而由Iterator支持的流的大小不是.类似地,操作map()是大小保持的,但是操作filter()破坏了任何大小的先验知识.流实现在启动终端操作之前知道管道的组合特征,因此它知道源是否大小以及是否所有阶段都是大小保留的,并且在这种情况下,可以简单地询问源的大小并绕过所有实际的流计算.(但是Java 8中的实现不会发生这种情况.)

请注意,流不需要专门用于支持这一点; Collection类创建了一个Spliterator知道其特性的流,因此不需要专门的Collections实现,只需更新共享实现以利用这一特定信息.

  • @Holger:对,我们跟踪的特征之一是"按自然顺序排序",其中没有明确的比较器的树集是已知的; 在第二个例子中,当前的实现是O(n). (4认同)