StringJoiner: detect or fix delimiter collision?

Philip Hodges philip.hodges at bluewin.ch
Mon Jan 27 01:12:28 UTC 2014


Please please please drop StringJoiner from Java 1.8 before it is too late.

It is not needed. It does not add value. It is an embarrassment.
We did without it for years. It is not long long overdue. We do not need it now.
It does not need to be in the very first Java 1.8 release.
Try leaving it out, and see if people even complain.
Most people won't even notice it, let alone be ready to misuse it straight away.

String.join is slower than Arrays.toString() or Collections.toString(). Test failed.
String.join(delimiter, iterable) needs extra code to call toString() if elements are not already CharSequence. Convenience? Test failed.
StringJoiner does not force or even remind the developer to consider delimiter collisions. Test failed.

It is a perfect complement for split: the hard to use interface that can't split the joined input reliably because it might have too many delimiters.

It will be the newest star on java antipattern web sites. A good place would be just after the item about not "Assembling XML with String operations" because the text parts might contain special characters.

Even if it ever did appear that StringJoiner and String.join did what we wanted,
I would still much rather roll my own than use the new StringJoiner in the library.
Then I could set the initial capacity of the StringBuilder, skip the defensive copies and null checks, and above all, introduce some extra mandatory method call to force the developer to tell the compiler what is being done about delimiter collisions, even if it is to add an assert that there are no delimiters in the added CharSequences, or to waive that check because numbers never never contain comma delimiters (hold on ... better check the locale to see if comma is used as a decimal point or grouping character after all).

I came across this non-justification [with my additions] on a blog:

"StringJoiner and String.join(...) are long, long overdue. They are so long overdue that the vast majority of Java developers likely have already written or have found [or have had to mend] utilities for joining strings [to make an unsplittable delimiter collision], but it is nice [or at least well-meant] for the JDK to finally provide this itself. Everyone has encountered situations where joining strings is required [and they forgot all about escaping, or should have used a PreparedStatement instead], and it is a Good Thing™ that we can now express that [bug opportunity] through a standard API that every [no, just some] Java developer (eventually) will know [of, but not actually use, and even if they do they will need an IDE to tell them that the prefix comes *after* the delimiter]."



> To quote Joshua Bloch on good API design: 'When in doubt leave it out' (or 'You can always add, but you can never remove')



> 
> 
> On 31 Aug 2013, at 23:13, Mike Duigou <mike.duigou at oracle.com> wrote:
> 
> 
> On Aug 30 2013, at 23:40 , Philip Hodges wrote:
>> ...
>> 
>> Why is there such a bandwagon rolling for this "convenience" feature?
> 
> Perhaps others just don't agree with you. The choice of functionality offered in the JDK 8 StringJoiner was not arbitrary or haphazardly chosen. If it doesn't meet your particular needs, I am sorry to hear that. Our belief as the proposers is that it offers a reasonable mix of functionality and simplicity to cover useful number of requirements. Our intent was certainly not to create the kitchen magician [1] of string joiners that attempted to incorporate every conceivable option. In particular your concerns about escaping are out of scope for the joiner in part because
> 
> Collection<String> strings;
> 
> String concat = strings.stream().map(MyUtils::escape).collect(Collections.joining(","));
> 
> seems like an adequate and flexible solution to most people.
> 
>> We already have joiners in apache commons and guava.
> 
> This is the reason that StringJoiner was considered for JDK--that many others were "rolling their own".
> 
>> At first I thought they were cool. Then I tried to use them in anger.
>> And was forced to roll my own.
> 
> I would encourage you to share your implementation or the javadocs as grist for discussion.  An actual alternative is the *only* thing that is likely to be persuasive.
> 
>> That can't be right.
> 
> Sometimes it is. The JDK doesn't make any attempt to satisfy everyone (or anyone). We all end up writing lots of non-business logic utility functions to bridge gaps in what JDK offers. This is normal. And, if it turns out to be something lots of people need then it's entirely possible that it could be added to the JDK.
> 
> Mike
> 
> [1] https://www.youtube.com/watch?v=cGVG9xLHb84
> 
>> 
>> A more elaborate offically blessed feature that
>> only does half the job is worse than useless.
>> Without the extra complex ability to detect or avoid collisions
>> it is neither "nice", nor a "Good Thing".
>> 
>> Phil
>> 
>> http://www.techempower.com/blog/2013/03/26/everything-about-java-8/
>> 
>> "StringJoiner and String.join(...) are long, long overdue. They are so long overdue that the vast majority of Java developers likely have already written or have found utilities for joining strings, but it is nice for the JDK to finally provide this itself. Everyone has encountered situations where joining strings is required, and it is a Good Thing™ that we can now express that through a standard API that every Java developer (eventually) will know. "
>> 
>> 
>> On 2013-07-23 22:09, Mike Duigou wrote:
>>> 
>>> On Jul 23 2013, at 12:43 , ph wrote:
>>> 
>>>> didn't see delimiter collision mentioned anywhere - are you really offering
>>>> an interface that only joins a list of entries without escaping or quoting
>>>> or even checking for separators (or escape or quote sequences) that might
>>>> occur in the entries?
>>> 
>>> Correct. StringJoiner makes no effort to address escaping/quoting.
>>> Doing so would add a lot of complexity that would not
>>> useful interesting to most users and probably still wouldn't satisfy everyone.
>> 
>>> If you wish some form of escaping or quoting you can pre-processed entries however you like before joining them.
>>> 
>>> Mike
>>> 
> 
> 




More information about the core-libs-dev mailing list