1. Overview
In this tutorial, we’ll see why and how to use the StringBuilder class in Scala.
2. String Concatenation
Often, we need to join two or more strings in our code. In Scala, this is typically done with the plus (+) operator:
scala> val s = "abc"
val s: String = abc
scala> val res = s + "def"
val res: String = abcdef
But let’s see what actually happens under the hood in the previous example.
Despite what we could initially think, we’re not adding more chars to the first string. If we look at the initial variable, we see that the value has been kept immutable. The same goes for the second variable:
scala> val s = "abc"
val s: String = abc
scala> val other = "def"
val other: String = def
scala> val res = s + other
val res: String = abcdef
scala> println(s)
abc
scala> println(other)
def
This is because we’re creating a new string each time with the chars of both strings. Strings are immutable objects that can’t be changed.
3. Performance Issues with String Concatenation
So, we’re creating a new string every time we concatenate strings. What does this mean? Creating a new object, such as our concatenated string, requires allocating memory for this new object. Typically, this is a non-issue for simple cases like our previous examples. But sometimes it’s something we need to take into account.
Imagine that we’re iterating through a huge Set of objects and that for each object we iterate through, we get some string representation and append it to an accumulator string. If our set is huge, this means we’re allocating a lot of new strings, and each one is bigger than the previous one! The last steps of the iteration can easily hold strings containing thousands of chars.
4. StringBuilder
Here’s where a StringBuilder can help us a lot. This class is used to represent mutable Strings and is optimized to perform String concatenations very efficiently. So, we should use it instead of the previous solution we just saw.
Take into account that the Scala StringBuilder class is basically an idiomatic wrapper to Java’s StringBuilder class:
scala> val sb = new StringBuilder("Example")
val sb: StringBuilder = Example
scala> val res = (sb ++= " of String Concatenation")
val res: sb.type = Example of String Concatenation
scala> println(res)
Example of String Concatenation
The StringBuilder class contains a few other useful methods. Let’s go through some of them.
4.1. Appending a Character
The first one we’re going to see is how to append a character to our StringBuilder. This can be done using a similar approach to what we saw for appending another String:
scala> val sb = new StringBuilder("Exampl")
val sb: StringBuilder = Exampl
scala> sb += 'e'
val res7: sb.type = Example
scala> println(sb)
Example
Notice that instead of using the ++= method as we did for appending strings, we’re using the += method for appending chars.
4.2. Appending Other Objects
If we need to append other objects, we need to use the .append method instead. This will work with any object like numbers or custom classes. For numbers, this would look like:
scala> val sb = new StringBuilder("Example: ")
val sb: StringBuilder = Example:
scala> sb.append(42)
val res14: StringBuilder = Example: 42
scala> println(sb)
Example: 42
And, for a custom case class, we can just append the class instance to the existing StringBuilder:
scala> case class MyExample(val i: Int)
class MyExample
scala> val obj = MyExample(42)
val obj: MyExample = MyExample(42)
scala> val sb = new StringBuilder("Example: ")
val sb: StringBuilder = Example:
scala> sb.append(obj)
val res16: StringBuilder = Example: MyExample(42)
scala> println(sb)
Example: MyExample(42)
4.3. Clearing the Contents
If we need to clear the current StringBuilder contents, we just need to use the .clear method, which would delete all the chars added so far:
scala> println(sb)
Example: MyExample(42)
scala> println(sb)
Example: MyExample(42)
scala> sb.clear()
scala> println(sb) //empty String will be printed
scala> sb.append(42)
val res21: StringBuilder = 42
scala> println(sb)
42
4.4. Deleting Characters
This class also allows deleting a substring of characters using the .delete method by specifying the start index and end index:
scala> val sb = new StringBuilder("Example")
val sb: StringBuilder = Example
scala> sb.delete(2,4)
val res24: StringBuilder = Exple
4.5. Converting to String
To convert from StringBuilder to String, we just need to call the .toString method:
scala> val sb = new StringBuilder("Example")
val sb: StringBuilder = Example
scala> sb.toString
val res25: String = Example
5. Conclusion
In this article, we saw how to do string concatenation in Scala using the StringBuilder. We also saw why using a naive concatenation operation can be problematic in some complex cases.