JavaStringBuilder & StringBuffer

StringBuilder & StringBuffer

String immutability is great for safety, but it has a downside: any code that builds up a string piece by piece ends up creating a lot of throwaway String objects. Java solves this with StringBuilder — a mutable, growable sequence of characters designed specifically for efficient text building.
The Problem: Repeated + Concatenation in a Loop
Every time you use + to concatenate Strings, Java creates a brand new String object to hold the combined result — the old strings are discarded. Do this once, and it's harmless. Do it thousands of times in a loop, and you're allocating and discarding a huge number of intermediate objects for no reason.

Inefficient: + concatenation in a loop

Java
public class SlowConcatDemo {
    public static void main(String[] args) {
        String result = "";

        for (int i = 0; i < 10_000; i++) {
            result = result + i + ","; // a NEW String object every iteration!
        }

        System.out.println(result.length());
    }
}
Warning
Each pass through this loop discards the previous result string entirely and builds a longer replacement from scratch. For 10,000 iterations, that's roughly 10,000 intermediate String objects created and immediately thrown away — real, measurable overhead that gets worse as the string grows.
The Fix: StringBuilder
StringBuilder maintains an internal, resizable character buffer that it mutates in place. Appending to it does not create a new object each time — it grows the same buffer, which is dramatically more efficient for repeated modifications.

Efficient: StringBuilder in a loop

Java
public class FastConcatDemo {
    public static void main(String[] args) {
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < 10_000; i++) {
            result.append(i).append(","); // mutates the same buffer
        }

        String finalString = result.toString();
        System.out.println(finalString.length());
    }
}
Tip
As a rule of thumb: use plain + concatenation for a handful of one-off string joins where readability matters most. Use StringBuilder whenever you're building a string incrementally inside a loop or across many steps.
Core StringBuilder Methods

Method

Purpose

.append(x)

Add x to the end of the buffer

.insert(index, x)

Insert x at a specific position

.delete(start, end)

Remove characters in a range

.reverse()

Reverse the entire character sequence

.toString()

Produce a regular, immutable String from the buffer

append, insert, delete, reverse, toString

Java
public class StringBuilderMethodsDemo {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();

        sb.append("Hello");
        sb.append(", ");
        sb.append("World");
        System.out.println(sb); // Hello, World

        sb.insert(5, "!!!");
        System.out.println(sb); // Hello!!!, World

        sb.delete(5, 8);
        System.out.println(sb); // Hello, World

        sb.reverse();
        System.out.println(sb); // dlroW ,olleH

        String finalResult = sb.toString();
        System.out.println(finalResult.getClass().getSimpleName());
    }
}
Hello, World
Hello!!!, World
Hello, World
dlroW ,olleH
String
Note
Unlike String methods, StringBuilder methods like .append(), .insert(), and .delete() modify the object in place and return the same builder (which is why you can chain them: sb.append("a").append("b")). When you're done building, call .toString() to get back a normal, immutable String you can use anywhere a String is expected.
StringBuffer: The Thread-Safe Sibling
StringBuffer is functionally almost identical to StringBuilder — same methods, same behavior — with one key difference: every method on StringBuffer is synchronized, meaning it is safe to share a single StringBuffer instance across multiple threads without corrupting its internal state.

Aspect

StringBuilder

StringBuffer

Thread-safe

No

Yes (synchronized methods)

Performance

Faster

Slower (synchronization overhead)

API

Identical methods

Identical methods

Introduced in

Java 5

Original Java (1.0)

Note
StringBuilder is preferred by default for the vast majority of code, because most string building happens entirely within a single thread (a single method, a single request) where thread safety is irrelevant overhead. Reach for StringBuffer only when you know a specific buffer will genuinely be mutated by multiple threads concurrently — synchronization has a real performance cost that isn't worth paying otherwise.