StringBuilder. When creating large strings in Java, concatenation ("+") becomes slow—this operation requires a lot of copying. StringBuilder can alleviate this problem.
Copying. StringBuilder speeds up concatenation by using a shared buffer. The buffer is mutable, so no copying is needed for appends.
Loop example. Here we import java.lang.StringBuilder. We use StringBuilder in a for-loop. StringBuilder optimizes cases where many append() calls occur.
Part 1 We create a StringBuilder. Then we use a for-loop and append 6 values (2 in each iteration) to the StringBuilder.
Part 2 We convert the data into a String object. We display the resulting String to the Console with the System.out.println method.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
// Part 1: create a new StringBuilder.
var builder = new StringBuilder();
// ... Loop and append values.
for (int i = 0; i < 3; i++) {
builder.append(i).append(" ");
}
// Part 2: convert to string.
var result = builder.toString();
// ... Print result.
System.out.println(result);
}
}0 1 2
Values. The StringBuilder can append many types of data. We are not restricted to strings. With the append() method, we can add ints, doubles, chars—any numeric type.
Part 1 We call append() on the result of a previous append() call. Append returns the original StringBuilder.
Part 2 We get a String instance from the StringBuilder with toString(), and write the String to the screen.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
int value1 = 300;
double value2 = 3.14;
short value3 = 5;
char value4 = 'A';
// Part 1: create StringBuilder and add 4 values to it.
StringBuilder builder = new StringBuilder();
builder.append(value1).append("\n");
builder.append(value2).append("\n");
builder.append(value3).append("\n");
builder.append(value4);
// Part 2: display results.
String result = builder.toString();
System.out.println(result);
}
}300
3.14
5
A
Insert. A StringBuilder has a mutable buffer. So we can quickly append, or insert, data. Here we use the insert method. It receives 2 arguments: an index, and a value we want to insert.
Argument 1 To insert after the second character, use the value 2. And to insert at the start, use zero.
Argument 2 We pass a string (or other value) as the second argument. This is the data that is placed into the StringBuilder.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
// Initialize StringBuilder with this value.
StringBuilder builder = new StringBuilder("ABC");
// Insert this substring at position 2.
builder.insert(2, "xyz");
System.out.println(builder);
}
}ABxyzC
IndexOf. A StringBuilder can be searched. We use the indexOf method to search for a substring within the StringBuilder's data. This method searches forward.
Note If the substring is found within the StringBuilder, the first index where it occurs is returned as an int.
Note 2 If no matching substring is found, the special value negative one is returned. We must often check for -1 when using indexOf.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abc");
// Try to find this substring.
int result = builder.indexOf("bc");
System.out.println(result);
// This substring does not exist.
int result2 = builder.indexOf("de");
System.out.println(result2);
}
}1
-1
Delete. This removes a range of characters. We pass it 2 int arguments. The first argument is the start index where removal is to begin. And the second argument is the end index.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("carrot");
// Delete characters from index 2 to index 5.
builder.delete(2, 5);
System.out.println(builder);
}
}cat
Replace. This method accepts 2 indexes and replaces the characters in that range with a specified String. Replace on StringBuilder works differently than replace() on Strings.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
// Create new StringBuilder.
StringBuilder b = new StringBuilder("ABC");
// Replace second character with "xyz".
b.replace(1, 2, "xyz");
System.out.println(b);
}
}AxyzC
Combine 2 StringBuilders. We can append one StringBuilder to another. We simply call append() and pass the second StringBuilder as an argument. The 2 StringBuilders are combined.
public class Program {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("cat");
StringBuilder builder2 = new StringBuilder("dog");
// Combine 2 StringBuilders.
builder.append(builder2);
System.out.println(builder);
}
}catdog
Substring. This method is found on the AbstractStringBuilder class. It provides the useful ability to extract a range of characters into a new string.
Info The first argument is the start index of the desired substring. The second argument is last index (not the character count).
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
builder.append("FOREST");
// Get substring after the first 2 characters.
String omitFirstTwo = builder.substring(2);
System.out.println(omitFirstTwo);
// Get only the first 2 characters in a substring.
String firstTwo = builder.substring(0, 2);
System.out.println(firstTwo);
}
}REST
FO
Loop over chars. A for-loop can iterate over the characters in a StringBuilder. We access the length() method to get the StringBuilder's size and then use charAt() to access chars.
Note The length() method returns the count of characters in the StringBuilder. The highest index is the count of chars minus one.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("magic");
// Loop over the characters in this StringBuilder.
for (int i = 0; i < builder.length(); i++) {
System.out.println(builder.charAt(i));
}
}
}m
a
g
i
c
SetLength. We can modify the length of a StringBuilder with setLength. This often is useful when we want to shorten or reduce the number of characters in the object.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("carrot");
// Use setLength to remove characters from the end.
builder.setLength(3);
System.out.println(builder);
}
}car
Capacity. The StringBuilder in Java manages its capacity as we add elements. The capacity will increase (double) the contents come close to filling it.
Here This program creates an empty StringBuilder. It uses for-loop to add 20 strings of 5 characters each to the StringBuilder.
Result The program prints out the length, and the capacity on each iteration. We see how the capacity changes.
Reverse. This example reverses a StringBuilder. It calls the reverse() method. This is an easy to reverse a string—we first must place its contents in a StringBuilder.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
// A StringBuilder can be reversed.
StringBuilder builder = new StringBuilder();
builder.append("abc");
builder.reverse();
System.out.println(builder);
}
}cba
Append performance. A StringBuilder is massively faster in repeated appends than a String. Append performance is the most important thing to know about StringBuilder.
Version 1 This version of the code adds 10,000 numbers (and spaces) to a string. We use the string concatenation operator.
Version 2 Here we perform many appends on a StringBuilder. The StringBuilder does not have a capacity set.
Result The String adds require significant time (251 ms) while the StringBuilder appends require less than 1 ms.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
// Version 1: add to string.
String value = "";
for (int i = 0; i < 10000; i++) {
value += Integer.toString(i) + ' ';
}
long t2 = System.currentTimeMillis();
// Version 2: append to StringBuilder.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 10000; i++) {
builder.append(i).append(' ');
}
long t3 = System.currentTimeMillis();
// ... Lengths are equal.
System.out.println(value.length());
System.out.println(builder.length());
// ... Times.
System.out.println(t2 - t1);
System.out.println(t3 - t2);
}
}48890
48890
251 ms, String + operator (20000 adds)
0 ms, StringBuilder append (20000 calls)
Capacity performance. Here we revisit capacity. How much does setting a capacity help if we know we will be adding as many as 1 million characters to our StringBuilder?
Version 1 In this test, the StringBuilder grows to a size of one million chars with no capacity set.
Version 2 The second StringBuilder meanwhile uses an exact capacity of 1,000,000. The two are benchmarked.
Result The exact capacity makes the second StringBuilder nearly twice as fast to complete its meaningless task.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
// Version 1: does not use capacity.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1000000; i++) {
builder.append(' ');
}
long t2 = System.currentTimeMillis();
// Version 2: uses exact capacity.
StringBuilder builder2 = new StringBuilder(1000000);
for (int i = 0; i < 1000000; i++) {
builder2.append(' ');
}
long t3 = System.currentTimeMillis();
// ... Times.
System.out.println(t2 - t1);
System.out.println(t3 - t2);
}
}10 ms, no capacity
6 ms, exact capacity
Append String versus char. Here is another benchmark. It compares calling append() with a one-character String literal versus a char. The String argument is slower.
Version 1 This version of the code appends a one-character String literal in a tight loop, repeated many times.
Version 2 Here we do not append a string, but instead append a single character—a character literal.
Result It is faster to use a char argument to append() than a String argument. I have found this helps many programs.
import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
// Version 1: appends one-char strings.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1000000; i++) {
builder.append("X");
}
long t2 = System.currentTimeMillis();
// Version 2: appends chars directly.
StringBuilder builder2 = new StringBuilder();
for (int i = 0; i < 1000000; i++) {
builder2.append('X');
}
long t3 = System.currentTimeMillis();
// ... Times.
System.out.println(t2 - t1);
System.out.println(t3 - t2);
}
}15 ms, append() String argument
7 ms, append() char argument
ContentEquals. With this method we can compare a String to a StringBuilder. The character data is compared. We call contentEquals on a String instance.
Summary. StringBuilder helps in many program parts. But often its best uses are in loops—many iterations occur, and many append calls are invoked.
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.
This page was last updated on Sep 14, 2024 (edit).