Java Language String concatenation and StringBuilders


Example

String concatenation can be performed using the + operator. For example:

String s1 = "a";
String s2 = "b";
String s3 = "c";
String s = s1 + s2 + s3; // abc

Normally a compiler implementation will perform the above concatenation using methods involving a StringBuilder under the hood. When compiled, the code would look similar to the below:

StringBuilder sb = new StringBuilder("a");
String s = sb.append("b").append("c").toString();

StringBuilder has several overloaded methods for appending different types, for example, to append an int instead of a String. For example, an implementation can convert:

String s1 = "a";
String s2 = "b";    
String s = s1 + s2 + 2; // ab2

to the following:

StringBuilder sb = new StringBuilder("a");
String s = sb.append("b").append(2).toString();

The above examples illustrate a simple concatenation operation that is effectively done in a single place in the code. The concatenation involves a single instance of the StringBuilder. In some cases, a concatenation is carried out in a cumulative way such as in a loop:

String result = "";
for(int i = 0; i < array.length; i++) {
    result += extractElement(array[i]);
}
return result;

In such cases, the compiler optimization is usually not applied, and each iteration will create a new StringBuilder object. This can be optimized by explicitly transforming the code to use a single StringBuilder:

StringBuilder result = new StringBuilder();
for(int i = 0; i < array.length; i++) {
    result.append(extractElement(array[i]));
}
return result.toString();

A StringBuilder will be initialized with an empty space of only 16 characters. If you know in advance that you will be building larger strings, it can be beneficial to initialize it with sufficient size in advance, so that the internal buffer does not need to be resized:

StringBuilder buf = new StringBuilder(30); // Default is 16 characters
buf.append("0123456789");
buf.append("0123456789"); // Would cause a reallocation of the internal buffer otherwise
String result = buf.toString(); // Produces a 20-chars copy of the string

If you are producing many strings, it is advisable to reuse StringBuilders:

StringBuilder buf = new StringBuilder(100);
for (int i = 0; i < 100; i++) {
    buf.setLength(0); // Empty buffer
    buf.append("This is line ").append(i).append('\n');
    outputfile.write(buf.toString());
}

If (and only if) multiple threads are writing to the same buffer, use StringBuffer, which is a synchronized version of StringBuilder. But because usually only a single thread writes to a buffer, it is usually faster to use StringBuilder without synchronization.

Using concat() method:

String string1 = "Hello ";
String string2 = "world";
String string3 = string1.concat(string2);  // "Hello world"

This returns a new string that is string1 with string2 added to it at the end. You can also use the concat() method with string literals, as in:

"My name is ".concat("Buyya");