StreamBuilder is awesome

Brian Goetz brian.goetz at
Thu Apr 11 12:46:38 PDT 2013

Yes, the precipitating cause was to mitigate the pain of taking away 
FlatMapper, but as you point out, it has other uses too.

Note that you could always use ArrayList as a stream builder, so its not 
like this is something you couldn't do at all before.  But it should be 
more efficient, since it requires fewer object creations and doesn't 
have to copy elements every time you overflow a buffer.

The streams that are built still retain reasonable parallelism.  The 
internal representation is an array of increasing-size arrays, so the 
spliterator first splits the "spine" array and then can split into the 
individual arrays.

We're still twiddling with the API to try to ensure that it can be done 
with minimum overhead for flatMap-like usages (after all, if we didn't 
care about overhead, we'd just say "use ArrayList".)

On 4/11/2013 3:31 PM, Ali Lahijani wrote:
> I just want to express my delight at this great new feature.
> StreamBuilder can be used to append to or concatenate Streams:
>          StreamBuilder<E> builder = Streams.builder();
>          s1.forEach(builder);
>          builder.accept(x);
>          builder.accept(y);
>          s2.forEach(builder);
>          Stream<E> stream =;
> And it can be used to create streams fluently, and in push mode, which
> is arguably the way that feels most natural in many situations.
>          StreamBuilder.OfInt builder = Streams.intBuilder();
>          for (int i = 0; i < 1000; i++) {
>              if (isPrime(i)) {
>                  build.accept(i)
>              }
>          }
>          IntStream stream =;
> Though admittedly, streams built this way might benefit much from
> Stream framework's support for parallelism.
> An observation:
> The call to build() at the end should always be put there, and exactly
> once. After that point, the builder should no longer be used. In line
> with these rules, I would prefer the following syntax:
>          Stream<E> -> {
>              s1.forEach(builder);
>              builder.accept(x);
>              builder.accept(y);
>              s2.forEach(builder);
>          });
> The implicit call to build() is inserted after the lambda returns,
> after which point the builder is no longer available to be used. I
> think it feels more natural, and a bit more Lambda-like.
> Once again, thanks for giving us this great new tool!
> Best

More information about the lambda-dev mailing list