Bits of Java – Episode 9: String vs StringBuilder

In this post I would like to review the difference between String and StringBuilder. The main difference between the two is that String is immutable, StringBuilder is not!

What does immutable mean? Well, it simply means that when you try to manipulate an immutable object what you are actually doing is to create a new object as a result of such manipulation.

In the String context, as a direct consequence of being immutable, every method which modifies the String actually returns a new String.


String aString = "Hi Ilenia";
String anotherString = aString.substring(3);

System.out.println(aString); //prints "Hi Ilenia"
System.out.println(anotherString); // prints "Ilenia"

aString.concat("! How are you?");
System.out.println(aString); //prints "Hi Ilenia"

Particularly interesting are the last two lines of the example. What we are doing is to concatenate our String with another one, but we are not assigning the result to anything, which is the reason why the next print statement still prints the original aString. This was never modified, but a new String was created with the content "Hi Ilenia! How are you?"; however, we are not assigning any variable to point to that object and so we cannot see the result! What we could have done is something like this:


String aString = "Hi Ilenia";
System.out.println(aString.concat("! How are you?")); //prints "Hi Ilenia! How are you?"

Here we are printing the result of the concatenation, which is the new String object, which contains "Hi Ilenia! How are you?".

When you write a program, you probably need to handle a lot of String, and, keeping in mind that every String manipulation actually produces a new object in memory, one could argue about the efficiency of such approach. Indeed, it is not the most efficient!

Which is why Java provides you with another object, the StringBuilder. As we said at the beginning, this is a mutable object, meaning that when we manipulate a StringBuilder we are not creating a new object in memory, but we get back a reference to the current object, which has been modified.


StringBuilder sb = new StringBuilder("Hi Ilenia");
sb.append("! How are you?");
System.out.println(sb); //prints "Hi Ilenia! How are you?"

As you can see from the example, in the second line, we are not assigning the result of the append operation to anything, because what it actually returns is a reference to our StringBuilder sb, and not to a new one. This is the reason why, printing sb will give as result the complete "Hi Ilenia! How are you?".

This requires a bit of attention, especially when you define multiple variables to reference the same StringBuilder.


StringBuilder sb = new StringBuilder("Hi Ilenia");
StringBuilder sb2 = sb;
sb.append("! How are you?");
System.out.println(sb); //prints "Hi Ilenia! How are you?"
System.out.println(sb2); //prints "Hi Ilenia! How are you?"

We have acted on sb with the append operation, but this modifies the object referenced by both sb and sb2, so, when we print the content of sb2 this also returns "Hi Ilenia! How are you?".

To conclude, keep in mind that if you need to perform a lot of String manipulation in your code, a more efficient approach would be to use a StringBuilder and, when you are happy with the result and you want back a String, you can simply use the toString() method!

Next time we will see another concept provided by Java to handle String object in an efficient way: the String pool!

by Ilenia Salvadori