Museful
Museful

Reputation: 6959

What is the best way to build a stream iteratively?

Suppose we have an algorithm that generates items sequentially in a loop (one item per iteration) and we want to put this algorithm into a method that returns a stream of those items.

Which approach is best; this one?

Stream<Cell> streamCellsTouchingRay(Point2D fromPoint, Vector2D direction){
    // ...
    Stream<Cell> stream = Stream.of(/* 1st item */);
    while(/* ... */){
        // ...
        stream = Stream.concat(stream, /* i'th item */);
    }
}

...or this one?

Stream<Cell> streamCellsTouchingRay(Point2D fromPoint, Vector2D direction){
    // ...
    ArrayList<Cell> cells = new ArrayList<>(/* required capacity is known */);
    cells.add(/* 1st item */);
    while(/* ... */){
        // ...
        cells.add(/* i'th item */);
    }
    return cells.stream();
}

...or another approach entirely?

Upvotes: 2

Views: 167

Answers (2)

Aiden Deom
Aiden Deom

Reputation: 916

  • Using an ArrayList will have a some copying overhead when you finally get the stream.

  • When using Stream.concat(), the docs note that you should use caution when concatenating many items:

Use caution when constructing streams from repeated concatenation. Accessing an element of a deeply concatenated stream can result in deep call chains, or even StackOverflowException.

Louis Wasserman's asnwer seems to be the best, if you are concatenating many items.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198023

Another approach entirely: use Stream.Builder.

Stream<Cell> streamCellsTouchingRay(Point2D fromPoint, Vector2D direction){
    // ...
    Stream.Builder<Cell> cells = Stream.builder();
    cells.add(/* 1st item */);
    while(/* ... */){
        // ...
        cells.add(/* i'th item */);
    }
    return cells.build();
}

Upvotes: 5

Related Questions