Why to use StringBuffer in Java instead of the string concatenation operator
Someone told me it's more efficient to use StringBuffer
to concatenate strings in Java than to use the +
operator for String
s. What happens under the hood when you do that? What does StringBuffer
do differently?
Solution 1:
It's better to use StringBuilder (it's an unsynchronized version; when do you build strings in parallel?) these days, in almost every case, but here's what happens:
When you use + with two strings, it compiles code like this:
String third = first + second;
To something like this:
StringBuilder builder = new StringBuilder( first );
builder.append( second );
third = builder.toString();
Therefore for just little examples, it usually doesn't make a difference. But when you're building a complex string, you've often got a lot more to deal with than this; for example, you might be using many different appending statements, or a loop like this:
for( String str : strings ) {
out += str;
}
In this case, a new StringBuilder
instance, and a new String
(the new value of out
- String
s are immutable) is required in each iteration. This is very wasteful. Replacing this with a single StringBuilder
means you can just produce a single String
and not fill up the heap with String
s you don't care about.
Solution 2:
For simple concatenations like:
String s = "a" + "b" + "c";
It is rather pointless to use StringBuffer
- as jodonnell pointed out it will be smartly translated into:
String s = new StringBuffer().append("a").append("b").append("c").toString();
BUT it is very unperformant to concatenate strings in a loop, like:
String s = "";
for (int i = 0; i < 10; i++) {
s = s + Integer.toString(i);
}
Using string in this loop will generate 10 intermediate string objects in memory: "0", "01", "012" and so on. While writing the same using StringBuffer
you simply update some internal buffer of StringBuffer
and you do not create those intermediate string objects that you do not need:
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 10; i++) {
sb.append(i);
}
Actually for the example above you should use StringBuilder
(introduced in Java 1.5) instead of StringBuffer
- StringBuffer
is little heavier as all its methods are synchronized.