Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create stream lazily

How can a stream be created lazily? During migration of collection based code I have run into this pattern multiple times:

Collection collection = veryExpensiveCollectionCreation();
return Stream.concat(firstStream, collection.stream());

The resulting concatenated stream is typically processed lazily, as we know. Therefore the expensive collection is not needed at all, if the stream processing stops in the first part of the concatenated stream.

So for performance reasons I would like to defer the creation of the entire collection until the concatenated stream actually tries to iterate the elements of the second part of the concatenation.

Pseudo code would look like

return Stream.concat(firstStream, new LazyStreamProvider() {
    Stream<Something> createStream() {
         return veryExpensiveCollectionCreation().stream();
    }
);

Edit: I'm aware refactoring the collection creation to streams would be best, to make all of the API stream aware. However, this is part of another component with a non modifiable API in this case.

like image 815
Bananeweizen Avatar asked Oct 04 '17 14:10

Bananeweizen


1 Answers

Maybe not the best solution but you can build your collection in the flatMap method so it will be built lazily :

return Stream.concat(
        firstStream, 
        Stream.of(Boolean.TRUE).flatMap(ignoredBoolean -> veryExpensiveCollectionCreation().stream())
);
like image 166
Olivier Boissé Avatar answered Sep 20 '22 17:09

Olivier Boissé