StringBuilder. In a string append, a new string must be created. A string cannot be changed. But with StringBuilder we add data to an internal buffer. This makes things faster.
With newBuilder, we create StringBuilders in Scala. With methods on the StringBuilder we append, insert, remove data. We can convert to a string.
Here we create a new StringBuilder called "builder." We use val to have a constant variable—but the internal data of the StringBuilder can still be changed.
Note Append() receives many types of arguments. But most commonly we add strings to a StringBuilder.
Note 2 The length is the number of characters within the StringBuilder. We can use "size" as an alternative.
Info Often we need a string to pass to another function as an argument. With toString we convert the StringBuilder to a string.
// Create a new StringBuilder.// ... Append two strings.
val builder = StringBuilder.newBuilder
builder.append("cat ")
builder.append("bird")
// Print the StringBuilder and its length.
println(builder)
println(builder.length)
// Convert StringBuilder to a string.
val result = builder.toString()
println(result)cat bird
8
cat bird
Append characters. Here is a more complex example. We process a custom format string. We have special characters in a string, and then insert values as we build up a StringBuilder.
Detail We loop over the "format" string with a for-loop. When the special chars are encountered, we append Ints to the StringBuilder.
Result The StringBuilder has numbers in place of the format chars. We use toString to get a final string representation.
// Use this as a custom format string.
val format = "Cats: @, dogs: %"
println(format)
// Create a new StringBuilder.
val builder = StringBuilder.newBuilder
val cats = 10
val dogs = 20
// Loop over the format string.// ... Append values in place of format characters.
for (i <- format.indices) {
if (format(i) == '@') {
builder.append(cats)
}
else if (format(i) == '%') {
builder.append(dogs)
}
else {
builder.append(format(i))
}
}
// Print the results.
val result = builder.toString()
println(result)Cats: @, dogs: %
Cats: 10, dogs: 20
Insert, replace. A StringBuilder's buffer is mutable. This makes operations like insert and replace faster. Here we test these functions.
Note With insert, we place a string beginning at an index. Later characters are moved to be after the new string.
Note 2 Replace() receives a start index, and an end index (not a length). We replace the first char with the arguments 0, 1.
val builder = StringBuilder.newBuilder
// Append initial data.
builder.append("I like cats")
println(builder)
// Insert this string at index 1.
builder.insert(1, " do not")
println(builder)
// Replace first character with a new string.
builder.replace(0, 1, "You")
println(builder)I like cats
I do not like cats
You do not like cats
ReplaceAllLiterally. This function does a replacement for all occurrences of the first argument. It replaces those substrings with the second argument (also a string).
Important This function returns a string. Unlike replace() it does not modify the StringBuilder's buffer.
val builder = StringBuilder.newBuilder
builder.append("two dogs, four dogs")
// Replace dogs with cats.// ... A new string is returned.
val result1 = builder.replaceAllLiterally("dogs", "cats")
println(result1)
// Replace two with three.
val result2 = builder.replaceAllLiterally("two", "three")
println(result2)two cats, four cats
three dogs, four dogs
Characters, charAt. We access StringBuilder characters with an index. We can directly use the index or call charAt. The first char is at 0, and the last is at the length minus one.
val letters = StringBuilder.newBuilder
letters.append("abc")
// Get the first char.// ... We can access the builder like a list or array.
val firstChar = letters(0)
// Use charAt to get second and last chars.
val secondChar = letters.charAt(1)
val lastChar = letters.charAt(letters.length - 1)
// Print our characters.
println(firstChar)
println(secondChar)
println(lastChar)a
b
c
Out of range. When accessing characters in a StringBuilder we must be careful to address an existing slot. Otherwise the "String index out of range" exception will appear.
val names = StringBuilder.newBuilder
names.append("mars")
// This will cause an error.
val c = names(400)Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 400
at java.lang.AbstractStringBuilder. charAt(Unknown Source)
at java.lang.StringBuilder. charAt(Unknown Source)
at scala.collection.mutable. StringBuilder.apply(StringBuilder.scala:117)...
Some thoughts. Some optimizations involve algorithms, bitwise operators, directed acyclic graphs. But often a StringBuilder is more important. It eliminates many strings. It speeds appends.
A review. StringBuilder is a performance optimization. But it is a necessary one. It optimizes appending (or inserting, or replacing) many strings at once, with no allocations.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.