一种在java stream api中指定Collector初始容量的优雅方法

时间:2016-12-09 21:30:00

标签: java-8 collectors

我试图找到一种在java stream api中设置收集器初始容量的好方法。最简单的例子是:

data.stream()
        .collect(Collectors.toList());

我只是想将一个带有list大小的int传递给collector,以便不调整内部数组的大小。第一个意图是这样做:

data.stream()
        .collect(Collectors.toList(data.size()));

但遗憾的是,toList没有重载以使用参数。我找到了一个解决方案,但它闻起来:

 data.stream()
        .collect(Collectors.toCollection(() -> new ArrayList<>(data.size())));

有没有办法表达它更简单?

3 个答案:

答案 0 :(得分:2)

我采取你不雅的

Collectors.toCollection(() -> new ArrayList<>(data.size()))

并将其包装在静态方法

public static <T> Collector<T, ?, List<T>> toList(int size) {
    return Collectors.toCollection(() -> new ArrayList<T>(size));
}

然后调用它(使用静态导入)

stream.collect(toList(size))

!不雅?

编辑(这确实使它成为 ArrayList )这是不是很糟糕?

答案 1 :(得分:1)

我不知道API中有任何直接的方法来确保在引擎盖下使用的可变容器的容量来收集数据。我可能会猜到至少其中一个原因是通过调用parallelStream()来支持并行性。

所以 - 如果您的数据是并行处理的,即使您知道底层容器(例如ArrayList)支持容量,也没有多大意义来提供初始容量。多个容器将由不同的线程创建,然后组合在一起,容量将至少损害整体性能。

如果你想要真正具体和优雅,你也可以尝试实现自己的收藏家。这并不困难。

答案 2 :(得分:0)

data.stream().collect(Collectors.toCollection(() -> new HashSet<>(100)))
data.stream().collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new HashSet<>(100)), Collections::unmodifiableSet))