Explain Codes LogoExplain Codes Logo

What's the best way to build a string of delimited items in Java?

java
string-join
string-builder
performance-optimization
Alex KataevbyAlex Kataev·Mar 12, 2025
TLDR

Join strings seamlessly with StringJoiner in Java 8:

StringJoiner stringJoiner = new StringJoiner(", "); // Hanging out with commas... stringJoiner.add("Apple").add("Banana").add("Cherry"); String result = stringJoiner.toString(); // "I've got: Apple, Banana, Cherry"

Outside the realm of Java 8, StringBuilder is your reliable workhorse:

StringBuilder builder = new StringBuilder(); // Let's do some fruit shopping! for (String fruit : Arrays.asList("Apple", "Banana", "Cherry")) { if (builder.length() > 0) builder.append(", "); builder.append(fruit); } String result = builder.toString(); // "I've got: Apple, Banana, Cherry"

Simpler join with String.join and TextUtils.join

When using collections, Java 8 pulled a rabbit out of its hat with String.join:

// Going to the fruit market! List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry"); String result = String.join(", ", fruits); // "Apple, Banana, Cherry"

For the Android aficionados, Android's TextUtils.join has got you covered:

String result = TextUtils.join(", ", new String[]{"Apple", "Banana", "Cherry"}); // And Look, I did the groceries in Android!

Looking beyond Java? The handy StringUtils.join function from Apache Commons Lang library has your back:

String result = StringUtils.join(fruits, ", "); // "Apple, Banana, Cherry"

Nulls and empty lists: Uninvited guests, anyone?

Check uninvited guests while building strings - handle potential empty lists or null elements:

StringJoiner joiner = new StringJoiner(", "); fruits.stream() .filter(Objects::nonNull) // No null party crashers allowed! .forEach(joiner::add); String result = joiner.toString();

Performance matters: Optimizing StringBuilder

Adding StringBuilder capacity upfront is worth considering when dealing with larger datasets:

int approximateSize = fruits.size() * estimatedItemSize; StringBuilder builder = new StringBuilder(approximateSize); // Give me some space... I've got heavy lifting to do!

Guava's Joiner: The alternative approch

Need a tool with some extra muscle? Try Guava's Joiner:

String result = Joiner.on(", ").skipNulls().join(fruits); // Heard about the skipping nulls party trick?

Handle delimiter: It's not just about commas!

In handmade string builds, don't get tripped over by improper delimiter management:

// Look I've got an extra tail! 🐒 String result = builder.toString(); // "Apple, Banana, Cherry,"

Say Hi to i18n: Going global friendly

Remember to account for i18n when creating globally-conscious applications:

// Single string, many languages Locale locale = ...; String delimiter = ResourceBundle.getBundle("delimiters", locale).getString("list_delimiter"); StringJoiner joiner = new StringJoiner(delimiter); // ... Add elements

Don't reinvent the wheel

There's a reason for the existence of these great libraries - they are robust, widely tested, and optimized.