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