When it comes to string manipulation in Java, we often face the dilemma of choosing between String
concatenation (+=
operator) and StringBuilder
. But which one should you choose and why?
The Problem
The problem arises when we need to concatenate multiple strings together. Naively using the + operator for concatenation can result in poor performance, especially when dealing with a large number of concatenations. This is due to the immutability of String objects in Java.
Solution 1: String Concatenation
Using String
concatenation with the +=
operator is a simple and intuitive approach. For example:
String result = "Hello";
result += " World";
However, when concatenating strings using +, each concatenation operation creates a new String object. This means that for each concatenation, memory allocation and copying of the content happens.
Solution 2: StringBuilder
StringBuilder
is a mutable class specifically designed for efficient string manipulation. Under the hood, the internal character array is modified directly when performing operations like appending or modifying the string. This avoids the need for creating new String objects for each concatenation.
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Hello");
stringBuilder.append(" World");
String result = stringBuilder.toString();
System.out.println(result);
We need to use the toString method to convert the StringBuilder object to a String because StringBuilder is a separate class. Using toString will allow us to work with the final concatenated string as a regular String object, which means we will be able to perform further operations or pass it to other parts of our code that expect a String type.
Microbenchmark
public class StringConcatenationBenchmark {
public static void main(String[] args) {
// Warm up the JVM
warmUp();
// String Concatenation Benchmark
long startTime = System.currentTimeMillis();
String concatenatedString = "";
for (int i = 0; i < 100000; i++) {
concatenatedString += "a";
}
long endTime = System.currentTimeMillis();
long stringConcatenationTime = endTime - startTime;
System.out.println("String Concatenation Time: " + stringConcatenationTime + "ms");
// StringBuilder Benchmark
startTime = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 100000; i++) {
stringBuilder.append("a");
}
concatenatedString = stringBuilder.toString();
endTime = System.currentTimeMillis();
long stringBuilderTime = endTime - startTime;
System.out.println("StringBuilder Time: " + stringBuilderTime + "ms");
}
public static void warmUp() {
String dummy = "";
for (int i = 0; i < 10000; i++) {
dummy += "a";
}
}
}
Results:
Conclusion
- StringBuilder generally outperforms String concatenation in terms of performance, especially when dealing with a large number of concatenations.
- String concatenation creates new String objects for each concatenation, resulting in potential memory allocation and content copying.
- StringBuilder provides efficient mutable string manipulation, avoiding the creation of multiple String objects.
- When performing simple concatenations, String concatenation can still be a good choice.