Skip to content
Laviyx Learn

Try

Java course menu

Java StringBuilder: Building Strings Efficiently

Learn when and how to use StringBuilder in Java: why string concatenation in loops is slow, append, insert, delete, reverse, setCharAt, converting with toString, chaining, and StringBuilder vs StringBuffer vs String.

Beginner8 min readUpdated
On this page

Because String objects are immutable, every + creates a new string. That is fine for a few joins, but building a long string piece by piece in a loop creates a new string on every iteration and copies all the text so far each time. StringBuilder is a mutable sequence of characters designed for exactly this job.

Building a string in a loop#

Java
public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 5; i++) {
            sb.append(i);
            if (i < 5) sb.append(", ");
        }
        String result = sb.toString();
        System.out.println(result);
    }
}
Output
1, 2, 3, 4, 5

append adds to the end of the same builder, with no new string per step. Call toString() at the end to get an ordinary String.

Why it matters#

Concatenating with += in a loop has to copy the whole string so far on each step, which takes O(n²) time in total. StringBuilder grows its internal buffer as needed, so the total is O(n). The difference is invisible for 10 pieces, and dramatic for 100,000:

Java
public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100_000; i++) {
            sb.append('x');
        }
        System.out.println(sb.length());
    }
}
Output
100000

The same loop with String s = ""; s += 'x'; does the same thing, but copies billions of characters along the way.

The main methods#

Java
public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello World");

        sb.append("!");              // Hello World!
        sb.insert(5, ",");           // Hello, World!
        sb.replace(7, 12, "Java");   // Hello, Java!
        System.out.println(sb);

        sb.delete(5, 6);             // Hello Java!
        sb.deleteCharAt(sb.length() - 1);
        sb.setCharAt(0, 'J');
        System.out.println(sb);

        System.out.println(sb.reverse());
        System.out.println(sb.length() + " " + sb.indexOf("o"));
    }
}
Output
Hello, Java!
Jello Java
avaJ olleJ
10 5
MethodEffect
append(x)Adds any value to the end
insert(index, x)Inserts at a position
delete(start, end)Removes characters from start up to end (exclusive)
deleteCharAt(index)Removes one character
replace(start, end, text)Replaces a range
setCharAt(index, c)Changes one character
reverse()Reverses the contents
toString()Returns a String

Chaining#

Most methods return the builder itself, so calls can be chained:

Java
public class Main {
    public static void main(String[] args) {
        String receipt = new StringBuilder()
                .append("Item: ").append("Notebook").append('\n')
                .append("Qty: ").append(4).append('\n')
                .append("Total: ").append(4 * 45.5)
                .toString();
        System.out.println(receipt);
    }
}
Output
Item: Notebook
Qty: 4
Total: 182.0

Reversing a string#

StringBuilder.reverse() is the standard one-liner:

Java
public class Main {
    public static void main(String[] args) {
        String word = "stressed";
        String reversed = new StringBuilder(word).reverse().toString();
        System.out.println(reversed);
    }
}
Output
desserts

When the compiler helps#

For a single expression like "Hello, " + name + "!", the compiler already generates efficient code, so you do not need a StringBuilder there. Use it when you build a string across many statements, especially in loops. For joining a collection with a separator, String.join or a stream's Collectors.joining is even simpler.

StringBuilder vs StringBuffer vs String#

StringStringBuilderStringBuffer
MutableNoYesYes
Thread-safeYes (immutable)NoYes (synchronized, slower)
Use forFixed text, map keysBuilding text in one threadLegacy code

Use StringBuilder in new code; StringBuffer is an older, synchronized version you will rarely need.

Common mistakes#

Practice#

Practice exercise

Using a StringBuilder, build the string "1-2-3-...-10" (the numbers 1 to 10 separated by dashes) and print it, then print the same string reversed.

Show solution
Java
public class Dashes {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 10; i++) {
            if (i > 1) sb.append('-');
            sb.append(i);
        }
        System.out.println(sb);
        System.out.println(sb.reverse());
    }
}
Output
1-2-3-4-5-6-7-8-9-10
01-9-8-7-6-5-4-3-2-1

reverse works on characters, so 10 becomes 01.

Key takeaway#

Finished this lesson?