Reputation: 6959
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
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
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