4 ways to concatenate Strings in Java [Example and Performance] (original) (raw)
When we think about String Concatenation in Java, what comes to our mind is the + operator, one of the easiest ways to join two String or a String, and a numeric in Java. Since Java doesn't support operator overloading, it's pretty special for String to have behavior. But in truth, it is the worst way of concatenating String in Java. When you concatenate two String using + operator e.g. "" + 101, one of the popular ways to convert int to String, compiler internally translates that to StringBuilder append call, which results in the allocation of temporary objects.
You can see the real difference in the performance of our example program, in which we have concatenated 100,000 String using the + operator. Anyway, this article is not just about + operator but also about other ways to concatenate multiple Strings.
There are four ways to do this, apart from the + operator, we can use StringBuffer, StringBuilder, and concat() method from java.lang.String class for the same purpose.
Both StringBuilder and StringBuffer classes are there for just this reason, and you can see that in our performance comparison. StringBuilder is the winner and the fastest way to concatenate Strings. StringBuffer is a close second, because of the synchronized method, and the rest of them are just 1000 times slower than them.
4 ways to concatenate String in Java
Here we will see examples of all four ways of concatenating Strings in Java. Starting with the most popular approach, joining string using + operator.
1. String Concatenation using + Operator
The easiest way of joining multiple String and numeric values in Java. Just remember that, when you have two or more primitive type values e.g. char, short, or int, at the beginning of your string concatenation, you need to explicitly convert the first of them to a String.
For example System.out.println(200 + 'B' + ""); will not print 200B, instead, it will print 266, by taking ASCII values of 'B' and adding them to 200.
On the other hand System.out.println("" + 200 + 'B') will print 200B. Unfortunately, this is the worst way to concatenate String in Java. Let's take a look at how the String concatenation operator works in Java. When we write :
String temp = "" + 200 + 'B';
it's translated into
new StringBuilder().append( "" ).append( 200 ).append('B').toString();
All + operator are translated into several StringBuilder.append() calls before final toString() call.
Since StringBuilder(String) constructor allocates a buffer with only 16 char, appending more than 16 characters will require buffer reallocation. At last, StringBuffer.toString() calls create a new String object with a copy of the StringBuilder buffer.
This means, to concatenate two String, you will need to allocate, one StringBuilder, one char array[16], one String object and another char[] of appropriate size to fit your input value. Imagine if you are doing these thousands of times in your application, it's not only slow but also increases the workload of Garbage Collector.
You can also see Java Performance The Definitive Guide By Scott Oaks to learn more about how to do performance testing in Java and how to tune different things in the Java ecosystem to get the best performance from your Java application.
2. Using concat() method from java.lang.String
Concat(String str) method concatenates the specified String to the end of this string. I have hardly seen this used for concatenation, though. Inside, it allocates a char[] of length equal to the combined length of two String, copies String data into it, and creates a new String object using private String constructor, which doesn't make a copy of input char[], as shown below.
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true);
}
/* * Package private constructor which shares value array for speed. * this constructor is always expected to be called with share==true. * a separate constructor is needed because we already have a public * String(char[]) constructor that makes a copy of the given char[]. */
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
The performance of concat() method is similar to the + operator and I don't recommend using it for any production purpose.
3. Using StringBuffer
This was the proper way to concatenate multiple String, integer, and others prior to Java 5 when StringBuilder was not available. It's much faster than the + operator and concert() method. The only drawback of this class is that all its append methods are synchronized.
Since we hardly share temporary string in a concurrent environment, the price for thread-safety is not desired in many cases, that's where StringBuilder is used.
It works similarly to StringBuilder synchronization. It also provides several overloaded append() methods to concatenate integer, char, short, etc.
4. Using StringBuilder
This is the best way to concatenate String in Java, especially when you are concatenating multiple Strings. It's not thread-safe, but you hardly need that during String concatenation. In the next section, we will see a performance comparison of all these 4 ways to concatenate String in Java.
From JDK 8 onwards, you can also use StringJoiner to concatenate in Java. I am not including StringJoiner in this article but you can also these 10 examples of StringJoiner to learn more about it.
Performance comparison + Operator vs Concat vs StringBuffer vs StringBuilder
here is a sample Java program to find out which method gives us best performance for String concatenation.
public class Demo{
public static void main(String args[]) throws IOException {
final int ITERATION = 100_000;
String s = "";
// String Concatenation using + operator
long startTime = System.nanoTime();
for (int i = 0; i < ITERATION; i++) {
s = s + Integer.toString(i);
}
long duration = (System.nanoTime() - startTime) / 1000;
System.out.println("Time taken to concatenate 100000
Strings using + operator (in micro) : " + duration);
// Using String concat() method
startTime = System.nanoTime();
for (int i = 0; i < ITERATION; i++) {
s.concat(Integer.toString(i));
}
duration = (System.nanoTime() - startTime) / 1000;
System.out.println("Time taken to concatenate 100000
Strings using concat method (in micro) : " + duration);
// StringBuffer example to concate String in Java
StringBuffer buffer = new StringBuffer(); // default size 16
startTime = System.nanoTime();
for (int i = 0; i < ITERATION; i++) {
buffer.append(i);
}
duration = (System.nanoTime() - startTime) / 1000;
System.out.println("Time taken to concatenate
100000 Strings using StringBuffer (in micro) : " + duration);
// StringBuilder example to concate two String in Java
StringBuilder builder = new StringBuilder();
//default size for worst case
startTime = System.nanoTime();
for (int i = 0; i < ITERATION; i++) {
builder.append(i);
}
duration = (System.nanoTime() - startTime) / 1000;
System.out.println("Time taken to concatenate
100000 Strings using StringBuilder append in micro) : " + duration);
}
}
Output: Time taken to concatenate 100000 Strings using + operator (in micro) : 29178349 Time taken to concatenate 100000 Strings using concat method (in micro) : 21319431 Time taken to concatenate 100000 Strings using StringBuffer (in micro) : 12557 Time taken to concatenate 100000 Strings using StringBuilder append (in micro) : 10641
You can clearly see that given everything the same, StringBuilder outperforms all others. It's almost 3000 times faster than + operator. concat() method is better than + operator but still very bad compared to StringBuffer and StringBuilder.
StringBuffer took more time than StringBuilder because of synchronized method. I know that, you hardly join 100K Strings but even for small numbers it adds. if you run program to join just 10 Strings, you will notice significant difference in time spent Here is what I got when I ran this program for 10 iteration only :
- operator took (in micros) : 177 concat() method took (in micros) : 28 StringBuffer took (in micros) : 21 StringBuilder append took (in micros) : 8
Though using the + operator along with empty String is easiest and obvious way to concatenate multiple String and numeric in Java, you should not use that, especially inside loops. Always use StringBuilder for string concatenation, the class is there for a reason, and if you are still using StringBuffer then get rid of that, because most of the time you don't really need the thread-safety overhead of StringBuffer.
Unfortunately, concat() method is only good when you need to concatenate exactly 2 strings. In short, always use StringBuilder to concatenate Strings in Java.