66

Say I want to create n items. Pre Java 8, I would write:

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

Is there an elegant way to use a stream to create n items?
I thought of this:

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

Is there a standard/better way of coding this?

Note that the actual usage is a bit more complex and using a stream would be more flexible because I can immediately pump the items through other functions in one line without even creating a reference to the list, for example grouping them:

Stream.iterate(0, i -> i).limit(10).map(o -> new MyClass())
    .collect(Collectors.groupingBy(...));
2
  • 2
    You think the stream will be more expressive/efficient/useful? For curiosity? Commented Jan 22, 2015 at 4:40
  • 4
    You can use an IntStream#range(0, N) and mapToObject. Commented Jan 22, 2015 at 5:01

2 Answers 2

110

You could use Stream#generate with limit:

Stream.generate(MyClass::new).limit(10);
Sign up to request clarification or add additional context in comments.

2 Comments

Why not Stream.iterate ?
@AsifMushtaq, because the state of each item is not dependent upon the previous one.
52

If you know n in advance, I think it's more idiomatic to use one of the stream sources that creates a stream that is known to have exactly n elements. Despite the appearances, using limit(10) doesn't necessarily result in a SIZED stream with exactly 10 elements -- it might have fewer. Having a SIZED stream improves splitting in the case of parallel execution.

As Sotirios Delimanolis noted in a comment, you could do something like this:

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

An alternative is this, though it's not clear to me it's any better:

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

You could also do this:

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

But this results in a fixed-size, though mutable, list.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.