使用流迭代n次而不是使用for循环来创建n个项目

时间:2015-01-22 03:15:12

标签: loops java-8 java-stream

说我要创建n个项目。在Java 8之前,我会写:

List<MyClass> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
    list.add(new MyClass());
}

是否有一种优雅的方式来使用流来创建n个项目?
我想到了这个:

List<MyClass> list = Stream.iterate(0, i -> i).limit(10)
    .map(o -> new MyClass()).collect(Collectors.toList());

是否有标准/更好的编码方式?

请注意,实际使用情况稍微复杂一些,使用流会更灵活,因为我可以立即通过一行中的其他函数抽取项目,甚至无需创建对列表的引用,例如将它们分组:

Stream.iterate(0, i -> i).limit(10).map(o -> new MyClass())
    .collect(Collectors.groupingBy(...));

2 个答案:

答案 0 :(得分:48)

您可以Stream#generate使用limit

Stream.generate(MyClass::new).limit(10);

答案 1 :(得分:33)

如果您事先知道 n ,我认为使用其中一个流源创建一个已知具有 n 元素。尽管出现了问题,但使用limit(10)并不一定会产生一个只有10个元素的SIZED流 - 它可能会有更少的元素。在并行执行的情况下,拥有SIZED流可以改善拆分。

正如Sotirios Delimanolis在评论中指出的那样,你可以这样做:

List<MyClass> list = IntStream.range(0, n)
    .mapToObj(i -> new MyClass())
    .collect(toList());

另一种选择就是这样,虽然我不清楚它是否更好:

List<MyClass> list2 = Collections.nCopies(10, null).stream()
    .map(o -> new MyClass())
    .collect(toList());

你也可以这样做:

List<MyClass> list = Arrays.asList(new MyClass[10]);
list.replaceAll(o -> new MyClass());

但是这导致了一个固定大小但是可变的列表。