Note that your original Java 8 code
System.out.println("items: " + stringList.stream().collect(Collectors.joining(", ")));
can be simplified to
System.out.println("items: " + String.join(", ", stringList));
In Java 7, you would have to use a StringBuilder
to do the same efficiently, but you may encapsulate it in a utility class, similar to Java 8’s StringJoiner
. Using a class with the same API allows to create Java 7 compatible code that is still easy to adapt to use the Java 8 counterpart.
However, it’s rather unlikely that this is the most performance critical part of your application, hence, you could use a pragmatic approach:
String s = stringList.toString();
System.out.append("items: ").append(s, 1, s.length()-1).println();
This simply doesn’t print the [
and ]
of the string representation, resulting in the desired comma separated list. While this string representation is not mandated, it would be hard to find an example of a useful collection implementation that doesn’t adhere to this convention (and you would know if you used such a class).
Regarding your updated question referring to something like “command pattern”, well, that doesn’t have to do anything with the Stream code of your question, but there are already abstractions, like the one used in the code above.
You could create a method like
static <A extends Appendable> A join(A target, CharSequence sep, List<?> data) {
try {
CharSequence currSep = "";
for(Object item: data) {
target.append(currSep).append(item.toString());
currSep = sep;
}
return target;
} catch(IOException ex) {
throw new IllegalStateException(ex);
}
}
which offers some flexibility, e.g. you could use it to acquire a String
:
String s = join(new StringBuilder(), ", ", stringList).toString();
System.out.println("items: " + s);
or just print:
join(System.out.append("items: "), ", ", stringList).println();