Joining Strings from a Stream
Build a separated, wrapped string in one pass, with no StringBuilder and no trailing comma.
Open this lesson in the learning hubKey points
Collectors.joining()glues elements together. The three argument form adds a separator, a prefix and a suffix.- It handles the trailing separator problem for you, which is where hand written loops usually go wrong.
- On an empty stream the three argument form still emits the prefix and suffix, so you get an empty pair of brackets.
- It only accepts CharSequence, so map numbers and objects to text first with
map(Object::toString). - No stream in play?
String.join(sep, collection)does the same job with less ceremony. - As a downstream collector inside
groupingByit builds one report line per group in a single pass.
Example
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> langs = List.of("Java", "Kotlin", "Scala");
System.out.println("plain : " + langs.stream().collect(Collectors.joining()));
System.out.println("commas : " + langs.stream().collect(Collectors.joining(", ")));
System.out.println("wrapped : " + langs.stream().collect(Collectors.joining(", ", "[", "]")));
System.out.println("empty : " + Stream.<String>empty().collect(Collectors.joining(", ", "[", "]")));
// No stream in play? String.join does the same job with less ceremony.
System.out.println("String : " + String.join(" | ", langs));
// joining only accepts CharSequence, so map numbers to text first.
System.out.println("ids : " + IntStream.rangeClosed(1, 4)
.mapToObj(Integer::toString).collect(Collectors.joining("-")));
// As a downstream collector it builds one report line per group.
Map<Integer, String> byLength = langs.stream().collect(Collectors.groupingBy(
String::length, TreeMap::new, Collectors.joining(" & ")));
System.out.println("grouped : " + byLength);
}
}
joining is the trailing comma bug you never have to fix again.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Streams course, and every lesson in it is listed on the Streams contents page.