Understanding Java 8 StringJoiner, String.join(), and Collectors.joining()
Java 8 introduced new and easy ways to join strings: StringJoiner, String.join(), and Collectors.joining().
These tools simplify combining multiple strings into a single string with delimiters and even allow adding prefixes and suffixes.
Let’s explore these methods with simple explanations and examples.
1. StringJoiner
The StringJoiner class, part of the java.util
package, is used to join strings with a delimiter.
You can also add an optional prefix and suffix to the final result. Internally, it uses a StringBuilder for better performance.
The StringJoiner class in Java 8 internally uses the StringBuilder class to efficiently construct and join strings.
How to Use
There are two ways to create a StringJoiner
:
StringJoiner(CharSequence delimiter)
This creates aStringJoiner
that joins strings using the specified delimiter.
Example:new StringJoiner(", ")
StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
This adds a prefix and suffix to the result.
Example:new StringJoiner(", ", "[", "]")
Example 1: Simple Delimiter
import java.util.StringJoiner;
public class StringJoinerExample {
public static void main(String[] args) {
StringJoiner joiner = new StringJoiner(", "); // Delimiter: ", "
// Add strings
joiner.add("Java");
joiner.add("Python");
joiner.add("C++");
System.out.println(joiner); // Output: Java, Python, C++
}
}
Example 2: Delimiter, Prefix, and Suffix
import java.util.StringJoiner;
public class StringJoinerExample {
public static void main(String[] args) {
// Create StringJoiner with delimiter, prefix, and suffix
StringJoiner joiner = new StringJoiner(", ", "[", "]");
// Add strings
joiner.add("Apple");
joiner.add("Banana");
joiner.add("Cherry");
// Print the joined string
System.out.println(joiner); // Output: [Apple, Banana, Cherry]
}
}
How It Works Internally
- StringBuilder Usage:
When you add strings to aStringJoiner
object, it uses aStringBuilder
to append each string with the specified delimiter, prefix, and suffix. This ensures optimal performance and avoids creating multiple intermediate string objects. - Efficient String Handling:
SinceStringBuilder
is mutable, appending strings is faster compared to concatenating strings directly using the+
operator, which creates new string objects for every operation.
2. String.join()
String.join()
is a simple, static method to join multiple strings with a delimiter.
This method can be used to join strings or array of strings or list of strings, but only with delimiter not with prefix and suffix.
String.join()
method in Java 8 internally uses the StringJoiner class.
Method Signatures
static String join(CharSequence delimiter, CharSequence... elements)
static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
How It Works
- Specify a delimiter (e.g., a space or comma).
- Pass either individual strings or a collection of strings.
Example
import java.util.Arrays;
public class StringJoinExample {
public static void main(String[] args) {
// Using varargs
String result = String.join(", ", "Java", "Python", "C++");
System.out.println(result); // Output: Java, Python, C++
// Using a collection
var languages = Arrays.asList("HTML", "CSS", "JavaScript");
String result2 = String.join(" | ", languages);
System.out.println(result2); // Output: HTML | CSS | JavaScript
}
}
How It Works Internally
- When you call
String.join()
, it creates aStringJoiner
object with the specified delimiter. - For each string in the input (array or collection), it uses the
StringJoiner.add()
method to append the string. - Finally, it calls the
StringJoiner.toString()
method to get the final result.
3. Collectors.joining()
Collectors.joining()
is a method from the Stream API.
It’s used to join elements of a stream into a single string, with options to specify a delimiter, prefix, and suffix.
Method Signatures
static Collector<CharSequence, ?, String> joining()
static Collector<CharSequence, ?, String> joining(CharSequence delimiter)
static Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
How It Works
- Combine it with a stream to join elements dynamically.
- Useful for lists, sets, or other collections.
Example
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class CollectorsJoiningExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("Mango", "Orange", "Grapes");
// Join with a delimiter
String result = fruits.stream()
.collect(Collectors.joining(", "));
System.out.println(result); // Output: Mango, Orange, Grapes
// Join with delimiter, prefix, and suffix
String resultWithPrefixSuffix = fruits.stream()
.collect(Collectors.joining(", ", "{", "}"));
System.out.println(resultWithPrefixSuffix); // Output: {Mango, Orange, Grapes}
}
}
Conclusion
- StringJoiner is great for dynamic string building with delimiters, prefixes, and suffixes.
- String.join() is the go-to method for quick joining of arrays or collections.
- Collectors.joining() is best for stream-based operations with added flexibility.