Skip to content
On this page

StringBuilder

The Java compiler performs special processing on String , allowing us to directly use + to concatenate strings.

Consider the following loop code:

java
String s = "";
for (int i = 0; i < 1000; i++) {
s = s + "," + i;
}

Although strings can be concatenated directly, in a loop, a new string object will be created each time it loops, and the old string will be thrown away. In this way, most strings are temporary objects, which not only wastes memory but also affects GC efficiency.

In order to efficiently splice strings, the Java standard library provides StringBuilder , which is a mutable object that can pre-allocate a buffer. In this way, when adding characters to StringBuilder , no new temporary objects will be created:

java
StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
    sb.append(',');
    sb.append(i);
}
String s = sb.toString();

StringBuilder can also perform chain operations:

java
public class Main {
    public static void main(String[] args) {
        var sb = new StringBuilder(1024);
        sb.append("Mr ")
          .append("Bob")
          .append("!")
          .insert(0, "Hello, ");
        System.out.println(sb.toString());
    }
}

If we look at the source code of StringBuilder , we can find that the key to chain operation is that the defined append() method will return this , so that it can continuously call other methods of itself.

Following the example StringBuilder , we can also design classes that support chain operations. For example, a counter that keeps incrementing:

java
public class Main {
    public static void main(String[] args) {
        Adder adder = new Adder();
        adder.add(3)
             .add(5)
             .inc()
             .add(10);
        System.out.println(adder.value());
    }
}

class Adder {
    private int sum = 0;

    public Adder add(int n) {
        sum += n;
        return this;
    }

    public Adder inc() {
        sum ++;
        return this;
    }

    public int value() {
        return sum;
    }
}

Note: For ordinary string + operations, we do not need to rewrite them as StringBuilder , because the Java compiler automatically encodes multiple consecutive + operations into StringConcatFactory operations during compilation. During runtime, StringConcatFactory will automatically optimize string concatenation operations into array copy or StringBuilder operations.

You may also have heard of StringBuffer , which is an early thread-safe version of Java's StringBuilder . It uses synchronization to ensure that it is safe for multiple threads to operate StringBuffer , but synchronization will bring about a decrease in execution speed.

StringBuilder and StringBuffer interfaces are exactly the same, and there is no need to use StringBuffer now.

Practise

Please use StringBuilder to construct an INSERT statement:

java
public class Main {
    public static void main(String[] args) {
        String[] fields = { "name", "position", "salary" };
        String table = "employee";
        String insert = buildInsertSql(table, fields);
        System.out.println(insert);
        String s = "INSERT INTO employee (name, position, salary) VALUES (?, ?, ?)";
        System.out.println(s.equals(insert) ? "Test ok" : "Test failed");
    }

    static String buildInsertSql(String table, String[] fields) {
        // TODO:
        return "";
    }
}

Summary

StringBuilder is a mutable object used to efficiently splice strings;

StringBuilder can support chain operations. The key to implementing chain operations is to return the instance itself;

StringBuffer is a thread-safe version of StringBuilder and is rarely used nowadays.

StringBuilder has loaded