You're on the right track by understanding the immutability of the String class.
Based on [1] and [2], here are some cases where each type of implementation is recommended:
1. Simple String Concatenation
String answer = firstPart + "." + secondPart;
This is syntactic sugar for
String answer = new StringBuilder(firstPart).append("."). append(secondPart).toString();
This is actually quite performant and is the recommended approach for simple string concatenation [1].
2. Stepwise Construction
String answer = firstPart;
answer += ".";
answer += secondPart;
Under the hood, this translates to
String answer = new StringBuilder(firstPart).toString();
answer = new StringBuilder(answer).append(".").toString();
answer = new StringBuilder(answer).append(secondPart).toString();
This creates a temporary StringBuilder and intermediate String objects which are inefficient [1]. Especially if the intermediate results are not used.
Use StringBuilder in this case.
3. For Loop Construction and Scaling For Larger Collections
String result = "";
for(int i = 0; i < numItems(); i++)
result += lineItem(i);
return result;
The above code is O(n^2), where n is number of strings. This is due to the immutability of the String class and due to the the fact that when concatenating two strings, the contents of both are copied [2].
So it may be fine for a few fixed length items, but it will not scale.
In such cases, use StringBuilder.
StringBuilder sb = new StringBuilder(numItems() * LINE_SIZE);
for(int i = 0; i < numItems(); i++)
sb.append(lineItem(i));
return b.toString();
This code is O(n) time, where n is number of items or strings. So as the number of strings gets larger, you will see the difference in performance [2].
This code pre-allocates an array in the initialization of StringBuilder, but even if a default size array is used, it will be significantly faster than the previous code for a large number of items [2].
Summary
Use string concatenation if you are concatenating only a few strings or if performance is not of importance (i.e. a demonstration/toy-application). Otherwise, use StringBuilder or consider processing the string as a character array [2].
References:
[1] Java Performance: The Definitive Guide by Scott Oaks: Link
[2] Effective Java 3rd Edition by Joshua Bloch: Link
Answer from mukundvemuri on Stack OverflowYou're on the right track by understanding the immutability of the String class.
Based on [1] and [2], here are some cases where each type of implementation is recommended:
1. Simple String Concatenation
String answer = firstPart + "." + secondPart;
This is syntactic sugar for
String answer = new StringBuilder(firstPart).append("."). append(secondPart).toString();
This is actually quite performant and is the recommended approach for simple string concatenation [1].
2. Stepwise Construction
String answer = firstPart;
answer += ".";
answer += secondPart;
Under the hood, this translates to
String answer = new StringBuilder(firstPart).toString();
answer = new StringBuilder(answer).append(".").toString();
answer = new StringBuilder(answer).append(secondPart).toString();
This creates a temporary StringBuilder and intermediate String objects which are inefficient [1]. Especially if the intermediate results are not used.
Use StringBuilder in this case.
3. For Loop Construction and Scaling For Larger Collections
String result = "";
for(int i = 0; i < numItems(); i++)
result += lineItem(i);
return result;
The above code is O(n^2), where n is number of strings. This is due to the immutability of the String class and due to the the fact that when concatenating two strings, the contents of both are copied [2].
So it may be fine for a few fixed length items, but it will not scale.
In such cases, use StringBuilder.
StringBuilder sb = new StringBuilder(numItems() * LINE_SIZE);
for(int i = 0; i < numItems(); i++)
sb.append(lineItem(i));
return b.toString();
This code is O(n) time, where n is number of items or strings. So as the number of strings gets larger, you will see the difference in performance [2].
This code pre-allocates an array in the initialization of StringBuilder, but even if a default size array is used, it will be significantly faster than the previous code for a large number of items [2].
Summary
Use string concatenation if you are concatenating only a few strings or if performance is not of importance (i.e. a demonstration/toy-application). Otherwise, use StringBuilder or consider processing the string as a character array [2].
References:
[1] Java Performance: The Definitive Guide by Scott Oaks: Link
[2] Effective Java 3rd Edition by Joshua Bloch: Link
You cannot change the original string because it is immutable therefore having String s = ""; every operation like
s += "something";
will create and reassign new object (probably it will also add a little bit of work for GC in near future). On he other hand modifying StringBuilder is (usually) not creating new object (indeed it is happening just once at the very end when calling toString() method on builder instance)
Because of this it is common to use StringBuilder when you are modifying string many many times (for example in some long loops).
Still it is common error to overuse StringBuilder - it may be example of premature optimization
Read also:
- Is it better to reuse a StringBuilder in a loop?
[Java] What exactly is stringBuilder and why use it instead of a traditional String?
Question about StringBuilder
Strings vs StringBuilder
You're not really going to find a better way to visualise it really unless you drew custom graphics, they do the same thing.
The explanation is the important part:
On each concatenation a new copy of the string is created, and is copied char by char. Iter 1 requires x chars copied. Iter 2 = 2x, 3= 3x and so on. Overall this equates to O(x + 2x +3x ..... +Kx) == O( xn2 ).
StringBuilder does the same functionality but uses a resizable array of all the strings and only copies them 1 time into a string when needed
More on reddit.comWhat happens when i use toString() method on a StringBuilder?
What is string builder in Java?
What are some of the benefits of StringBuilder?
List out some Java String builder methods
Videos
Going through firecode.io and saw this solution (to replace spaces with a certain string)
public static String replace(String a, String b) {
String ans = "";
for (char c: a.toCharArray() ){
if (c == ' '){ ans += b; }
else { ans += c; }
}
return ans;
}A user commented and said:
Use StringBuilder instead - it's more efficient! String does not allow appending. Each method you invoke on a String creates a new object and returns it. This is because String is immutable - it cannot change its internal state. On the other hand StringBuilder is mutable. When you call append(..) it alters the internal char array, rather than creating a new string object.
I'm curious about this and wanted to ask (I'm new to Java):
-
If a traditional 'String' is immutable, why am I able to use it in a "+=" operation to append a char at the end?
-
So when you use the "+=" operation, the computer instantiates a brand new String object each and every time you do it? So effectively I'm creating/destroying multiple String objects over and over again with every "+="?
-
Coming from C++, I see a lot of the "+=" operation when working with strings. Is it the same situation in C++ as it is expressed here in Java?
So I get that StringBuilders are more efficient than concatenating strings with the "+" operator, because they are manipulating the underlying char[] array. But here's what I don't understand.
Let's look at case 1, where we are appending a string to the StringBuilder inside the parentheses. Doesn't this mean that for every time we call this statement, a new string has to be created and then appended to the StringBuilder?
StringBuilder().append("my new string"); // "my new string" needs to be created every time!
Now let's look at case 2, where we create a premade string, and then we append it to the StringBuilder. Wouldn't this be more efficient, because we can loop through the append statement as many times as we want without creating a new String?
String myString = "hello world";
StringBuilder.append(myString); // myString is already created!
Hope this makes sense. Asking because I'm writing a program that will potentially need to do this same operation millions of times per day, and want to get a better understanding.