3

What are the benefits of using a StringBuilder method over a String? Why not just amend the content within a String?

I understand that a StringBuilder is mutable, but if you have to write more lines of code to append onto it, why not change the original String?

I'd appreciate it if someone would provide an example of where a StringBuilder would be more beneficial.

Grace BL
  • 39
  • 1
  • 4

2 Answers2

4

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:

m.antkowicz
  • 13,268
  • 18
  • 37
  • @user16320675 Good point! – m.antkowicz Oct 14 '21 at 20:06
  • @user16320675: that's true, but there is a big difference between "resize and copy an array when it exceeds a certain threshold" and "create a new copy of an array/string for every single operation to it". – Joachim Sauer Oct 14 '21 at 20:12
  • In many cases though java compiler can optimize the work and there won't be much difference. I believe in 99% of the situation there won't be difference. So for simple situation I think string + can be more readable without downside. If there is a complex building of string the stringbuilder also gives you better readability which is nice. I would consider more the cleanness of the code than performance – Veselin Davidov Oct 14 '21 at 20:16
  • @VeselinDavidov: `StringBuilder` is necessary specifically when constructing a big string in a loop. In most other cases it's unnecessary. – Joachim Sauer Oct 14 '21 at 20:53
0

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

m_vemuri
  • 672
  • 3
  • 10