Home > Articles

This chapter is from the book

7.4 Class StringBuilder

We now discuss the StringBuilder class’s features for creating and manipulating modifiable string information. Every StringBuilder can store a number of characters specified by its capacity. When that capacity is exceeded, a StringBuilder expands its capacity to accommodate more characters—the new capacity is twice the old capacity plus 2.

In programs that frequently perform String concatenation or other String modifications, implementing those operations with a StringBuilder is more efficient and avoids creating unnecessary extra String objects. Java can perform optimizations involving String objects—such as referring to one String object from multiple variables—because it knows these objects will not change. Use Strings for text that does not change.

7.4.1 Creating StringBuilder Objects

Class StringBuilder provides four constructors for initializing new StringBuilder objects. Figure 7.10 demonstrates three of these:

  • Line 6 uses the no-argument StringBuilder constructor to create an empty StringBuilder with a default capacity of 16 characters.

  • Line 7 uses the StringBuilder constructor with an integer argument to create an empty StringBuilder and the specified initial capacity (10 in this case). If you know the final size of the content you’ll build, you can use this constructor to preallocate that capacity, making your program more efficient because the StringBuilder will not have to expand to accommodate more text.

  • Line 8 uses the StringBuilder constructor that takes a String argument to create a StringBuilder containing the String’s characters. The StringBuilder’s initial capacity is the String’s length plus 16.

Lines 10–12 implicitly invoke StringBuilder method toString to output the contents of each StringBuilder.

 1   // Fig. 7.10: StringBuilderConstructors.java
 2   // StringBuilder constructors.
 3
 4   public class StringBuilderConstructors {
 5      public static void main(String[] args) {
 6         var buffer1 = new StringBuilder();
 7         var buffer2 = new StringBuilder(10);
 8         var buffer3 = new StringBuilder("hello");
 9
10         System.out.printf("buffer1 = \"%s\"%n", buffer1);
11         System.out.printf("buffer2 = \"%s\"%n", buffer2);
12         System.out.printf("buffer3 = \"%s\"%n", buffer3);
13      }
14   }
buffer1 = ""
buffer2 = ""
buffer3 = "hello"

Fig. 7.10 | StringBuilder constructors.

7.4.2 Methods length, capacity, setLength and ensureCapacity

The StringBuilder class’s length and capacity methods return the number of characters currently in a StringBuilder and the number of characters that can be stored without allocating more memory, respectively. StringBuilder’s ensureCapacity method guarantees that a StringBuilder has at least the specified capacity, increasing the capacity if necessary. StringBuilder’s setLength method increases or decreases the length of a StringBuilder. Figure 7.11 demonstrates these methods.

 1   // Fig. 7.11: StringBuilderCapLen.java
 2   // StringBuilder length, setLength, capacity and ensureCapacity methods.
 3
 4   public class StringBuilderCapLen {
 5      public static void main(String[] args) {
 6         var buffer = new StringBuilder("Hello, how are you?");
 7
 8         System.out.printf("buffer = %s%nlength = %d%ncapacity = %d%n%n",
 9            buffer.toString(), buffer.length(), buffer.capacity());
10
11         buffer.ensureCapacity(75);
12         System.out.printf("New capacity = %d%n%n", buffer.capacity());
13
14         buffer.setLength(10);
15         System.out.printf("New length = %d%nbuffer = %s%n",
16            buffer.length(), buffer.toString());
17      }
18   }
buffer = Hello, how are you?
length = 19
capacity = 35

New capacity = 75

New length = 10
buffer = Hello, how

Fig. 7.11 | StringBuilder length, setLength, capacity and ensureCapacity methods.

The program contains one StringBuilder called buffer. Line 6 uses the StringBuilder constructor that takes a String argument to initialize the StringBuilder with "Hello, how are you?". Lines 8–9 print the StringBuilder’s contents, length and capacity. The buffer’s initial capacity is 35 because the constructor that takes a String argument initializes the capacity to the String’s length plus 16.

Line 11 calls ensureCapacity to expand the StringBuilder’s capacity to a minimum of 75 characters. The StringBuilder’s capacity remains unchanged if it’s more than method ensureCapacity’s argument.

Dynamically increasing a StringBuilder’s capacity frequently can degrade performance. If a StringBuilder’s size will increase repeatedly, setting its capacity high will improve performance by reducing the number of times the StringBuilder needs to reallocate its internal array.

Line 14 uses method setLength to set the length of the StringBuilder to 10. If the specified length is less than the StringBuilder’s length, its contents are truncated to the specified length—the subsequent characters are discarded. If the specified length is greater than the StringBuilder’s length, null characters ('\0') are appended until the StringBuilder’s total number of characters is equal to the specified length.

Generative AI

1 Prompt genAIs to explain why a StringBuilder adds 16 to its capacity when you initialize it with a String.

2 Section 7.4’s introduction mentioned that when a StringBuilder’s capacity is exceeded, it expands such that “the new capacity is twice the old capacity plus 2." Prompt genAIs to write Java code demonstrating this growth pattern.

7.4.3 Methods charAt, setCharAt, getChars and reverse

You can manipulate a StringBuilder’s characters with StringBuilder methods charAt, setCharAt, getChars and reverse (Fig. 7.12):

  • Method charAt (line 10) takes an integer argument and returns the character in the StringBuilder at that index.

  • Method getChars (line 13) copies characters from a StringBuilder into the character array passed as an argument. This method takes four arguments—the starting index from which characters should be copied, the index one past the last character to be copied, the character array into which to copy the characters and the starting index in the character array where the first copied character should be placed.

  • Method setCharAt (lines 20 and 21) takes an index and a character argument, and replaces the StringBuilder’s character at that index with the character argument.

  • Method reverse (line 24) reverses the contents of the StringBuilder.

For the StringBuilder methods that receive indices, attempting to access a character outside the bounds of the StringBuilder causes a IndexOutOfBoundsException.

 1   // Fig. 7.12: StringBuilderChars.java
 2   // StringBuilder methods charAt, setCharAt, getChars and reverse.
 3
 4   public class StringBuilderChars {
 5      public static void main(String[] args) {
 6         var buffer = new StringBuilder("hello there");
 7
 8         System.out.printf("buffer = %s%n", buffer.toString());
 9         System.out.printf("Character at 0: %s%nCharacter at 4: %s%n%n",
10            buffer.charAt(0), buffer.charAt(4));
11
12         char[] charArray = new char[buffer.length()];
13         buffer.getChars(0, buffer.length(), charArray, 0);
14         System.out.print("The characters are: ");
15
16         for (char character : charArray) {
17            System.out.print(character);
18         }
19
20         buffer.setCharAt(0, 'H');
21         buffer.setCharAt(6, 'T');
22         System.out.printf("%n%nbuffer = %s", buffer.toString());
23
24         buffer.reverse();
25         System.out.printf("%n%nbuffer = %s%n", buffer.toString());
26      }
27   }
buffer = hello there
Character at 0: h
Character at 4: o

The characters are: hello there

buffer = Hello There

buffer = erehT olleH

Fig. 7.12 | StringBuilder methods charAt, setCharAt, getChars and reverse.

Generative AI

1 Prompt genAIs with the code in Fig. 7.12, asking them to simplify the code and explain the changes they make.

7.4.4 append Methods

The StringBuilder class’s overloaded append methods (Fig. 7.13) add values of various types to the end of a StringBuilder. Versions are provided for each primitive type, character arrays, Strings, Objects, and more. Each method takes its argument, converts it to a String and appends it to the StringBuilder. In this example, the call

System.lineSeparator()

returns the system-specific line separator, which varies among operating systems.

 1   // Fig. 7.13: StringBuilderAppend.java
 2   // StringBuilder append methods.
 3
 4   public class StringBuilderAppend {
 5      public static void main(String[] args) {
 6         Object objectRef = "hello";
 7         String string = "goodbye";
 8         char[] charArray = {'a', 'b', 'c', 'd', 'e', 'f'};
 9         boolean booleanValue = true;
10         char characterValue = 'Z';
11         int integerValue = 7;
12         long longValue = 10000000000L;
13         float floatValue = 2.5f;
14         double doubleValue = 33.333;
15
16         var lastBuffer = new StringBuilder("last buffer");
17         var buffer = new StringBuilder();
18
19         buffer.append(objectRef)
20               .append(System.lineSeparator())
21               .append(string)
22               .append(System.lineSeparator())
23               .append(charArray)
24               .append(System.lineSeparator())
25               .append(charArray, 0, 3)
26               .append(System.lineSeparator())
27               .append(booleanValue)
28               .append(System.lineSeparator())
29               .append(characterValue)
30               .append(System.lineSeparator())
31               .append(integerValue)
32               .append(System.lineSeparator())
33               .append(longValue)
34               .append(System.lineSeparator())
35               .append(floatValue)
36               .append(System.lineSeparator())
37               .append(doubleValue)
38               .append(System.lineSeparator())
39               .append(lastBuffer);
40
41         System.out.printf("buffer contains%n%s%n", buffer.toString());
42      }
43   }
buffer contains
hello
goodbye
abcdef
abc
true
Z
7
10000000000
2.5
33.333
last buffer

Fig. 7.13 | StringBuilder append methods.

Implementing + and += for Strings

The compiler can use StringBuilder and the append methods to implement the + and += String concatenation operators to avoid creating unnecessary extra String objects. For example, assuming the declarations

String string1 = "hello";
String string2 = "BC";
int value = 22;

the statement

String s = string1 + string2 + value;

concatenates "hello", "BC" and 22. The concatenation can be performed as follows:

String s = new StringBuilder().append("hello").append("BC").
   append(22).toString();

First, the preceding statement creates an empty StringBuilder, then appends the Strings "hello" and "BC" and the integer 22. Next, StringBuilder’s toString method converts the StringBuilder to a String object to be assigned to String s. The statement

s += "!";

can be performed as follows:

s = new StringBuilder().append(s).append("!").toString();

This creates an empty StringBuilder, then appends the current contents of s followed by "!". Next, StringBuilder’s method toString (which must be called explicitly here) returns the StringBuilder’s contents as a String, and the result is assigned to s.

Generative AI

1 Prompt genAIs to rewrite the code in Fig. 7.13 to use String concatenation with the + operator, then compare the generated code to Fig. 7.13.

7.4.5 Insertion and Deletion Methods

The StringBuilder class’s overloaded insert methods insert values of various types at any valid position in a StringBuilder. Versions are provided for the primitive types, character arrays, Strings, Objects and more. Each method takes its second argument and inserts it at the index specified by the first argument. If the first argument is less than 0 or greater than the StringBuilder’s length, a StringIndexOutOfBoundsException occurs. The StringBuilder class’s delete and deleteCharAt methods delete characters at any position in a StringBuilder:

  • delete takes two arguments—the starting index and the index one past the end of the characters to delete. All characters beginning at the starting index up to but not including the ending index are deleted.

  • deleteCharAt takes one argument—the index of the character to delete.

Invalid indices cause both methods to throw a StringIndexOutOfBoundsException. Figure 7.14 demonstrates methods insert, delete and deleteCharAt.

 1   // Fig. 7.14: StringBuilderInsertDelete.java
 2   // StringBuilder methods insert, delete and deleteCharAt.
 3
 4   public class StringBuilderInsertDelete {
 5      public static void main(String[] args) {
 6         Object objectRef = "hello";
 7         String string = "goodbye";
 8         char[] charArray = {'a', 'b', 'c', 'd', 'e', 'f'};
 9         boolean booleanValue = true;
10         char characterValue = 'K';
11         int integerValue = 7;
12         long longValue = 10000000;
13         float floatValue = 2.5f; // f suffix indicates that 2.5 is a float
14         double doubleValue = 33.333;
15
16         var buffer = new StringBuilder();
17
18         buffer.insert(0, objectRef);
19         buffer.insert(0, "  "); // each of these contains two spaces
20         buffer.insert(0, string);
21         buffer.insert(0, "  ");
22         buffer.insert(0, charArray);
23         buffer.insert(0, "  ");
24         buffer.insert(0, charArray, 3, 3);
25         buffer.insert(0, "  ");
26         buffer.insert(0, booleanValue);
27         buffer.insert(0, "  ");
28         buffer.insert(0, characterValue);
29         buffer.insert(0, "  ");
30         buffer.insert(0, integerValue);
31         buffer.insert(0, "  ");
32         buffer.insert(0, longValue);
33         buffer.insert(0, "  ");
34         buffer.insert(0, floatValue);
35         buffer.insert(0, "  ");
36         buffer.insert(0, doubleValue);
37
38         System.out.printf(
39            "buffer after inserts:%n%s%n%n", buffer.toString());
40
41         buffer.deleteCharAt(10); // delete 5 in 2.5
42         buffer.delete(2, 6); // delete .333 in 33.333
43
44         System.out.printf(
45            "buffer after deletes:%n%s%n", buffer.toString());
46      }
47   }
buffer after inserts:
33.333  2.5  10000000  7  K  true  def  abcdef  goodbye  hello

buffer after deletes:
33  2.  10000000  7  K  true  def  abcdef  goodbye  hello

Fig. 7.14 | StringBuilder methods insert, delete and deleteCharAt.

Generative AI

1 Prompt genAIs asking why some Java String and StringBuilder methods throw IndexOutOfBoundsExceptions but others throw StringIndexOutOfBoundsExceptions?

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.