StringJoiner in b88

Brian Goetz brian.goetz at
Fri May 17 07:28:14 PDT 2013

Yes, this is a regrettable weakness of Collector which I spent some time 
trying to address and ultimately concluded it wasn't worth the added 

Here's the problem: the delimiter version of StringJoiner is basically a 
sequential construct.  When we parallelize a mutable reduction, the 
Collector primitives are:

  - make new result container
  - incorporate a new result into the container
  - merge two containers

The invariant that is the equivalent of the associativity constraint for 
reduction is:

   add(new(), t1, t2) == combine(add(new(), t1), add(new(), t2))

Stringjoiner with no prefix/suffix meets these rules; we can create two 
StringJoiners and stuff elements into them:

   sj1: a, b, c, d
   sj2: e, f, g, h

and then combine them with sj1.add(sj2):

   sj1: a, b, c, d, e, f, g, h

With prefix/suffix, it does not, because we'd have extra prefixes and 

   sj1: [ a, b, c, d ]
   sj2: [ e, f, g, h ]

joined: [ a, b, c, d, [ e, f, g, h ] ]

In order to fix this, Collector would have to know whether we're at the 
root of the computation tree, and if so, invoke new with different 

The workaround is simple, but not as pretty as you want:

   StringJoiner sj = new StringJoiner(",", "[", "]");
   String result = sj.toString();

In other words, you can still do exactly what you want with relatively 
few additional lines of code, but the penalty is dropping out of the 
fluent model.

On 5/17/2013 3:32 AM, Joe Bowbeer wrote:
> Previously, when StringJoiner was a stream destination, I could collect
> into one using the three-arg variant:
>    s.into(new StringJoiner(delimiter, prefix, suffix));
> For example:
>    elements.into(new StringJoiner(", ", "[", "]"));
> But I can't now because Collectors.toStringJoiner(delimiter) is the only
> option.
> What's the recommended workaround?
> Should Collectors.toStringJoiner(delimiter, prefix, suffix) be added?
> On Mon, May 6, 2013 at 5:56 AM, Brian Goetz <brian.goetz at
> <mailto:brian.goetz at>> wrote:
>     There has not been a "stream destination" type or an "into" method
>     for a very long time.
>     But, if you want to use a string joiner as a stream target, do:
>        stream.collect(toStringJoiner(__));
>     On 5/6/2013 3:19 AM, Joe Bowbeer wrote:
>         In b88, StringJoiner does not implement a stream destination?
>         Is the "into" example in the javadoc no longer valid?
>         <>
>         Joe

More information about the lambda-libs-spec-observers mailing list