_Original issue created by sven.linstaedt on 2013-04-30 at 09:25 AM_
At the moment it is not possible to join a String over iterable elements by mapping the elements to String with a customized function like:
Joiner.on(String sep, Function<Object, CharSequence> toStringFunction);
or even better a typed version like:
Joiner.<T>on(String sep, Function super T, CharSequence> toStringFunction).join(Iterable extends T> elements);
_Original comment posted by tomas.zalusky on 2013-04-30 at 12:39 PM_
What about
Joiner.on(sep).join(Iterables.transform(elements,toStringFunction))
or
Joiner.on(sep).join(FluentIterable.from(elements).transform(toStringFunction))
?
BTW this would be cool (especially with static imports) although violating principle of orthogonality:
FluentIterable.from(elements).transform(toStringFunction).join(Joiner.on(sep))
_Original comment posted by wasserman.louis on 2013-04-30 at 03:19 PM_
We have come to the conclusion generally that we'd prefer for Joiner to remain strictly focused on the act of joining things, and this, too, would fall into the category of "If we add something to do this, we'd want it to be part of (or at least based on) a more full-featured API for producing parseable strings (e.g. writing CSV strings), which would include escaping and such."
Status: Duplicate
Merged Into: #1064
_Original comment posted by sven.linstaedt on 2013-05-01 at 08:03 AM_
Sounds reasonable. I was not aware of Iterables#transform.
This actually was a pretty good request. I was trying to do this today and ended up having to iterate the list twice... one to transform my objects to strings and then again to join. This is such a simple change and such a nice feature, its not clear to me why it was rejected.
This is a basic issue of separation-of-concerns. Most libraries should have one clear purpose, but be composable with other utilities to get more complex behaviors. Joiner's purpose is to join things.
Side note: Joiner usage should probably be phased out in favor of new JDK 8 functionality such as Collectors.joining().
Keeping the separation of concerns just because it's named Joiner is really limiting. Maybe create MappingJoiner if it's a big deal.
Regardless, looks like Collectors does what I need so thanks for the suggestion.
Can you explain a little more about why you'd need to "iterate the list twice" in the absence of this feature? Iterables.transform doesn't actually iterate its input, it just makes a wrapper. Joiner.join(Iterables.transform(collection, function)) seems to do exactly what you want without any extra effort.
Interesting. I used Iterables.transform() and IntelliJ had me convert it to a stream/map/collect. If Iterables.transform() doesn't do the map/collect first but only does it when iterated, that is indeed a good solution.
@bhardwick Yeah, IntelliJ is pretty zealous IMO when it suggests replacing Guava constructs like Iterables.transform with stream/map/collect (the former is _lazy_, whereas the latter is _eager_ despite being based on streams).
Thus I'd personally suggest that you treat those particular suggestions from IntelliJ with a pinch of salt. :)
Most helpful comment
Can you explain a little more about why you'd need to "iterate the list twice" in the absence of this feature? Iterables.transform doesn't actually iterate its input, it just makes a wrapper.
Joiner.join(Iterables.transform(collection, function))seems to do exactly what you want without any extra effort.