When building strings in loops or through multiple concatenations, performance can suffer dramatically. StringBuilder provides a mutable buffer that grows efficiently, making it useful for generated text such as reports, CSV output, HTML, or SQL.

Why StringBuilder?

String concatenation creates new String objects. StringBuilder keeps one mutable buffer and appends into it.

Performance.java
public class Performance {
    public static void main(String[] args) {
        int count = ;

        String names = "";
        for (int i = 1; i <= count; i++) {
            names = names + "Name" + i;
            if (i < count) {
                names = names + ", ";
            }
        }
        System.out.println(names);

        StringBuilder builder = new StringBuilder();
        for (int i = 1; i <= count; i++) {
            builder.append("Name").append(i);
            if (i < count) {
                builder.append(", ");
            }
        }
        System.out.println(builder.toString());
    }
}
public class Performance {
    public static void main(String[] args) {
        int count = ;

        String names = "";
        for (int i = 1; i <= count; i++) {
            names = names + "Name" + i;
            if (i < count) {
                names = names + ", ";
            }
        }
        System.out.println(names);

        StringBuilder builder = new StringBuilder();
        for (int i = 1; i <= count; i++) {
            builder.append("Name").append(i);
            if (i < count) {
                builder.append(", ");
            }
        }
        System.out.println(builder.toString());
    }
}
mutability StringBuilder can be changed after creation, unlike String, which creates a new object for every modification.

Basic Operations

Use append to add values to the end of a builder.

Basics.java
// StringBuilder basics

public class Basics {

    public static void main(String[] args) {
        // Create empty StringBuilder
        String first = ;
        String second = ;
        StringBuilder sb1 = new StringBuilder();
        sb1.append(first);
        sb1.append(" ");
        sb1.append(second);
        System.out.println(sb1.toString());

        // Create with initial string
        StringBuilder sb2 = new StringBuilder("Java");
        System.out.println(sb2);

        // Create with initial capacity
        StringBuilder sb3 = new StringBuilder(50);
        sb3.append("Efficient");
        System.out.println("Length: " + sb3.length());
        System.out.println("Capacity: " + sb3.capacity());

        // Append different types
        StringBuilder sb4 = new StringBuilder();
        sb4.append("Age: ");
        sb4.append(25);
        sb4.append(", Score: ");
        sb4.append(95.5);
        sb4.append(", Active: ");
        sb4.append(true);
        System.out.println(sb4);
    }

}
// StringBuilder basics

public class Basics {

    public static void main(String[] args) {
        // Create empty StringBuilder
        String first = ;
        String second = ;
        StringBuilder sb1 = new StringBuilder();
        sb1.append(first);
        sb1.append(" ");
        sb1.append(second);
        System.out.println(sb1.toString());

        // Create with initial string
        StringBuilder sb2 = new StringBuilder("Java");
        System.out.println(sb2);

        // Create with initial capacity
        StringBuilder sb3 = new StringBuilder(50);
        sb3.append("Efficient");
        System.out.println("Length: " + sb3.length());
        System.out.println("Capacity: " + sb3.capacity());

        // Append different types
        StringBuilder sb4 = new StringBuilder();
        sb4.append("Age: ");
        sb4.append(25);
        sb4.append(", Score: ");
        sb4.append(95.5);
        sb4.append(", Active: ");
        sb4.append(true);
        System.out.println(sb4);
    }

}
// StringBuilder basics

public class Basics {

    public static void main(String[] args) {
        // Create empty StringBuilder
        String first = ;
        String second = ;
        StringBuilder sb1 = new StringBuilder();
        sb1.append(first);
        sb1.append(" ");
        sb1.append(second);
        System.out.println(sb1.toString());

        // Create with initial string
        StringBuilder sb2 = new StringBuilder("Java");
        System.out.println(sb2);

        // Create with initial capacity
        StringBuilder sb3 = new StringBuilder(50);
        sb3.append("Efficient");
        System.out.println("Length: " + sb3.length());
        System.out.println("Capacity: " + sb3.capacity());

        // Append different types
        StringBuilder sb4 = new StringBuilder();
        sb4.append("Age: ");
        sb4.append(25);
        sb4.append(", Score: ");
        sb4.append(95.5);
        sb4.append(", Active: ");
        sb4.append(true);
        System.out.println(sb4);
    }

}
// StringBuilder basics

public class Basics {

    public static void main(String[] args) {
        // Create empty StringBuilder
        String first = ;
        String second = ;
        StringBuilder sb1 = new StringBuilder();
        sb1.append(first);
        sb1.append(" ");
        sb1.append(second);
        System.out.println(sb1.toString());

        // Create with initial string
        StringBuilder sb2 = new StringBuilder("Java");
        System.out.println(sb2);

        // Create with initial capacity
        StringBuilder sb3 = new StringBuilder(50);
        sb3.append("Efficient");
        System.out.println("Length: " + sb3.length());
        System.out.println("Capacity: " + sb3.capacity());

        // Append different types
        StringBuilder sb4 = new StringBuilder();
        sb4.append("Age: ");
        sb4.append(25);
        sb4.append(", Score: ");
        sb4.append(95.5);
        sb4.append(", Active: ");
        sb4.append(true);
        System.out.println(sb4);
    }

}
append append adds content to the end of the StringBuilder and returns the same builder.

Insert and Delete

StringBuilder can also modify text in the middle of the buffer.

InsertDelete.java
// Insert and delete operations

public class InsertDelete {

    public static void main(String[] args) {
        // Insert
        StringBuilder sb1 = new StringBuilder("Hello World");
        sb1.insert(6, "Beautiful ");
        System.out.println(sb1);  // Hello Beautiful World

        // Insert at beginning
        StringBuilder sb2 = new StringBuilder("Java");
        sb2.insert(0, "I love ");
        System.out.println(sb2);  // I love Java

        // Insert at end (same as append)
        StringBuilder sb3 = new StringBuilder("Start");
        sb3.insert(sb3.length(), " End");
        System.out.println(sb3);  // Start End

        // Delete range
        StringBuilder sb4 = new StringBuilder("Hello Beautiful World");
        sb4.delete(6, 16);  // Remove "Beautiful "
        System.out.println(sb4);  // Hello World

        // Delete single character
        StringBuilder sb5 = new StringBuilder("Helllo");
        sb5.deleteCharAt(3);  // Remove extra 'l'
        System.out.println(sb5);  // Hello

        // Replace
        StringBuilder sb6 = new StringBuilder("Hello World");
        sb6.replace(6, 11, "Java");
        System.out.println(sb6);  // Hello Java
    }

}

Method Chaining

Chaining.java
// Method chaining

public class Chaining {

    public static void main(String[] args) {
        // Method chaining
        StringBuilder sb = new StringBuilder();
        sb.append("First")
          .append(" ")
          .append("Second")
          .append(" ")
          .append("Third");
        System.out.println(sb);

        // Build a sentence
        String sentence = new StringBuilder()
            .append("The")
            .append(" quick")
            .append(" brown")
            .append(" fox")
            .toString();
        System.out.println(sentence);

        // Mix different operations
        String result = new StringBuilder()
            .append("Count: ")
            .append(10)
            .append(", ")
            .append("Value: ")
            .append(3.14)
            .toString();
        System.out.println(result);

        // Build CSV line
        String csv = new StringBuilder()
            .append("John")
            .append(",")
            .append(30)
            .append(",")
            .append("Engineer")
            .append(",")
            .append(75000)
            .toString();
        System.out.println(csv);
    }

}
method_chaining Because append returns the same builder, multiple append calls can be chained into a fluent sequence.

Reverse

StringBuilder includes utility methods for reversing, changing characters, resizing, and extracting substrings.

Reverse.java
// Reverse and other operations

public class Reverse {

    public static void main(String[] args) {
        // Reverse string
        StringBuilder sb1 = new StringBuilder("Hello");
        sb1.reverse();
        System.out.println(sb1);  // olleH

        // Check palindrome
        String word = ;
        StringBuilder sb2 = new StringBuilder(word);
        boolean isPalindrome = word.equals(sb2.reverse().toString());
        System.out.println(word + " is palindrome: " + isPalindrome);

        // Set character at index
        StringBuilder sb3 = new StringBuilder("Hello");
        sb3.setCharAt(0, 'J');
        System.out.println(sb3);  // Jello

        // Set length (truncate or pad)
        StringBuilder sb4 = new StringBuilder("Hello");
        sb4.setLength(3);
        System.out.println(sb4);  // Hel

        StringBuilder sb5 = new StringBuilder("Hi");
        sb5.setLength(5);  // Pads with null chars
        System.out.println("Length: " + sb5.length());

        // Substring
        StringBuilder sb6 = new StringBuilder("Hello World");
        String sub = sb6.substring(6, 11);
        System.out.println(sub);  // World
    }

}
// Reverse and other operations

public class Reverse {

    public static void main(String[] args) {
        // Reverse string
        StringBuilder sb1 = new StringBuilder("Hello");
        sb1.reverse();
        System.out.println(sb1);  // olleH

        // Check palindrome
        String word = ;
        StringBuilder sb2 = new StringBuilder(word);
        boolean isPalindrome = word.equals(sb2.reverse().toString());
        System.out.println(word + " is palindrome: " + isPalindrome);

        // Set character at index
        StringBuilder sb3 = new StringBuilder("Hello");
        sb3.setCharAt(0, 'J');
        System.out.println(sb3);  // Jello

        // Set length (truncate or pad)
        StringBuilder sb4 = new StringBuilder("Hello");
        sb4.setLength(3);
        System.out.println(sb4);  // Hel

        StringBuilder sb5 = new StringBuilder("Hi");
        sb5.setLength(5);  // Pads with null chars
        System.out.println("Length: " + sb5.length());

        // Substring
        StringBuilder sb6 = new StringBuilder("Hello World");
        String sub = sb6.substring(6, 11);
        System.out.println(sub);  // World
    }

}
// Reverse and other operations

public class Reverse {

    public static void main(String[] args) {
        // Reverse string
        StringBuilder sb1 = new StringBuilder("Hello");
        sb1.reverse();
        System.out.println(sb1);  // olleH

        // Check palindrome
        String word = ;
        StringBuilder sb2 = new StringBuilder(word);
        boolean isPalindrome = word.equals(sb2.reverse().toString());
        System.out.println(word + " is palindrome: " + isPalindrome);

        // Set character at index
        StringBuilder sb3 = new StringBuilder("Hello");
        sb3.setCharAt(0, 'J');
        System.out.println(sb3);  // Jello

        // Set length (truncate or pad)
        StringBuilder sb4 = new StringBuilder("Hello");
        sb4.setLength(3);
        System.out.println(sb4);  // Hel

        StringBuilder sb5 = new StringBuilder("Hi");
        sb5.setLength(5);  // Pads with null chars
        System.out.println("Length: " + sb5.length());

        // Substring
        StringBuilder sb6 = new StringBuilder("Hello World");
        String sub = sb6.substring(6, 11);
        System.out.println(sub);  // World
    }

}

Practical Use

StringBuilder is useful for building structured text in loops or from many parts.

Practical.java
// Practical: HTML builder

public class Practical {

    public static String buildTable(String[][] data) {
        StringBuilder html = new StringBuilder();

        html.append("<table>\n");

        // Header row
        if (data.length > 0) {
            html.append("  <thead>\n    <tr>");
            for (String header : data[0]) {
                html.append("<th>").append(header).append("</th>");
            }
            html.append("</tr>\n  </thead>\n");
        }

        // Data rows
        html.append("  <tbody>\n");
        for (int i = 1; i < data.length; i++) {
            html.append("    <tr>");
            for (String cell : data[i]) {
                html.append("<td>").append(cell).append("</td>");
            }
            html.append("</tr>\n");
        }
        html.append("  </tbody>\n");

        html.append("</table>");

        return html.toString();
    }

    public static String buildSelectQuery(String table, String[] columns, String condition) {
        StringBuilder sql = new StringBuilder();

        sql.append("SELECT ");

        if (columns.length == 0) {
            sql.append("*");
        } else {
            for (int i = 0; i < columns.length; i++) {
                if (i > 0) sql.append(", ");
                sql.append(columns[i]);
            }
        }

        sql.append(" FROM ").append(table);

        if (condition != null && !condition.isEmpty()) {
            sql.append(" WHERE ").append(condition);
        }

        sql.append(";");

        return sql.toString();
    }

    public static void main(String[] args) {
        // Build HTML table
        String[][] tableData = {
            {"Name", "Age", "City"},
            {"Alice", "25", "New York"},
            {"Bob", "30", "London"},
            {"Charlie", "35", "Paris"}
        };

        System.out.println(buildTable(tableData));

        // Build SQL queries
        System.out.println("\n" + buildSelectQuery("users", new String[0], null));
        System.out.println(buildSelectQuery("users", new String[]{"name", "email"}, null));
        System.out.println(buildSelectQuery("users", new String[]{"*"}, "age > 25"));
    }

}

Exercise: Practical.java

Build a comma-separated list of names from an array, handling the last element without a trailing comma