StringBuilder in Java

Naveen AnamaneniUpdated · 5 min read

A String can never change, which is great for sharing but wasteful when you're building text piece by piece, like a bill with many lines or a report in a loop. Every "change" to a String creates a whole new object. StringBuilder is the opposite: a string you can change. It keeps the characters in one growing buffer, so adding to it is fast, and when you're done you turn it into a normal String with toString().

Building a Bill

Bill.java▶ Try it
public class Bill {
    public static void main(String[] args) {
        String[] items = {"Rice", "Dal", "Ghee"};
        int[] prices = {120, 95, 250};
 
        StringBuilder bill = new StringBuilder("Bill for Advitha\n");
        int total = 0;
        for (int i = 0; i < items.length; i++) {
            bill.append(items[i]).append(": Rs. ")
                .append(prices[i]).append('\n');
            total += prices[i];
        }
        bill.append("Total: Rs. ").append(total);
 
        String result = bill.toString();
        System.out.println(result);
    }
}
Output
Bill for Advitha
Rice: Rs. 120
Dal: Rs. 95
Ghee: Rs. 250
Total: Rs. 465

How it works

  1. new StringBuilder("Bill for Advitha\n") starts the buffer with some text.
  2. append adds to the end. It accepts strings, numbers, characters, anything, and returns the same builder, so calls can be chained.
  3. No new string is created while building; the same buffer grows.
  4. toString() creates the final String once, at the end.

Editing in Place

Edit.java▶ Try it
public class Edit {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello World");
        sb.setCharAt(0, 'J');
        System.out.println(sb);
 
        sb.insert(0, ">> ");
        System.out.println(sb);
 
        sb.replace(3, 8, "Hi");
        System.out.println(sb);
 
        sb.delete(0, 3);
        System.out.println(sb);
 
        sb.reverse();
        System.out.println(sb);
    }
}
Output
Jello World
>> Jello World
>> Hi World
Hi World
dlroW iH
MethodWhat it does
append(x)Add x at the end
insert(i, x)Add x at position i
delete(start, end)Remove characters from start up to end (end excluded, like substring)
deleteCharAt(i)Remove one character
replace(start, end, text)Replace a range with new text
setCharAt(i, c)Change one character
reverse()Reverse the whole content
length(), charAt(i), indexOf(text)Read it, like a String
setLength(n)Cut it to n characters (or pad with \0)
toString()The finished String

How the Buffer Grows

Capacity is room; length is what's used

A StringBuilder keeps an internal array with some spare room. length() is the number of characters you've added; capacity() is how many fit before it must grow. An empty builder starts with room for 16. When it runs out, it allocates a bigger array (about double plus 2) and copies the characters over. Doubling means growing is rare, so appending stays fast on average.

StringBuilder and equals

StringBuilder does not override equals, so two builders with the same text are not equals. Compare their contents with sb1.toString().equals(sb2.toString()), sb1.compareTo(sb2) == 0, or "text".contentEquals(sb).

Common Mistakes

Using StringBuilder for two or three pieces on one line. Plain + is just as fast there and easier to read.

Comparing builders with equals. It compares objects, not text.

Sharing one builder between threads. It isn't thread-safe; see "StringBuffer vs StringBuilder".

Interview Corner

What is StringBuilder and when should you use it?

StringBuilder is a mutable sequence of characters. Its append, insert, delete, replace and reverse methods change the same object instead of creating new strings, and toString() produces the final immutable String. Use it when text is built in many steps or inside a loop; for a few pieces in one expression, + is fine.

What is the difference between length() and capacity() in StringBuilder?

length() is the number of characters currently stored. capacity() is the size of the internal buffer, the number of characters it can hold before it must allocate a bigger array. The default capacity is 16, and it grows to about twice the old size plus 2 when full.

Practice

  1. Easy: Use a StringBuilder to build the times table of 7 (7 x 1 = 7 up to 7 x 10 = 70), one line each, then print it.
  2. Harder: Write static String mask(String card) that keeps only the last 4 digits of a card number and replaces every earlier digit with X, using setCharAt.

Quick check: StringBuilder

4 questions
1What does new StringBuilder("ab").append("cd").reverse() contain?
2What is the capacity of new StringBuilder()?
3What does append return?
4How do you get a String from a StringBuilder?

Key Takeaways

Was this tutorial helpful?

Lesson 198 of 482