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.

count
Performance.java
Replay: real traced execution (multi-file project)
public class Performance {
    public static void main(String[] args) {
        int count = 3;

        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 = 5;

        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());
    }
}
  1. count ← 3, names ← (empty)

    1public class Performance {2    public static void main(String[] args) {3        int count→ 3 = 3; //@count=3, 545        String names→ (empty) = "";6        for (int i = 1; i <= count; i++) {
  2. names ← Name1

    pass 1 of 3
    5String names = "";6for (int i1 = 1; i <= count3; i++) {7    names→ Name1 = names + "Name" + i1;8    if (i < count) {
    All 3 passes — pass 1 is the card above
    passinames
    11(empty) Name1
    22Name1, Name1, Name2
    33Name1, Name2, Name1, Name2, Name3
  3. names ← Name1,

    pass 1 of 2
    7names = names + "Name" + i;8if (i1 < count3) {9    names→ Name1,  = names + ", ";10}
  4. names ← Name1, Name2,

    pass 2 of 2
    7names = names + "Name" + i;8if (i2 < count3) {9    names→ Name1, Name2,  = names + ", ";10}
  5. builder ← (empty)

    11}12System.out.println(namesName1, Name2, Name3);1314StringBuilder builder→ (empty) = new StringBuilder();15for (int i = 1; i <= count; i++) {
    outputName1, Name2, Name3
  6. for (int i = 1; i <= count; i++)

    pass 1 of 3
    14StringBuilder builder = new StringBuilder();15for (int i1 = 1; i <= count3; i++) {16    builder.append("Name").append(i1);17    if (i < count) {
    All 3 passes — pass 1 is the card above
    passi
    11
    22
    33
  7. if (i < count)

    pass 1 of 2
    16builder.append("Name").append(i);17if (i1 < count3) {18    builder.append(", ");19}
  8. if (i < count)

    pass 2 of 2
    16builder.append("Name").append(i);17if (i2 < count3) {18    builder.append(", ");19}
  9. System.out.println(builder.toString());

    20    }21    System.out.println(builder.toString());22}
    outputName1, Name2, Name3
  1. count ← 5, names ← (empty)

    1public class Performance {2    public static void main(String[] args) {3        int count→ 5 = 5;45        String names→ (empty) = "";6        for (int i = 1; i <= count; i++) {
  2. names ← Name1

    pass 1 of 5
    5String names = "";6for (int i1 = 1; i <= count5; i++) {7    names→ Name1 = names + "Name" + i1;8    if (i < count) {
    All 5 passes — pass 1 is the card above
    passinames
    11(empty) Name1
    22Name1, Name1, Name2
    33Name1, Name2, Name1, Name2, Name3
    44Name1, Name2, Name3, Name1, Name2, Name3, Name4
    55Name1, Name2, Name3, Name4, Name1, Name2, Name3, Name4, Name5
  3. names ← Name1,

    pass 1 of 4
    7names = names + "Name" + i;8if (i1 < count5) {9    names→ Name1,  = names + ", ";10}
    All 4 passes — pass 1 is the card above
    passinames
    11Name1 Name1,
    22Name1, Name2 Name1, Name2,
    33Name1, Name2, Name3 Name1, Name2, Name3,
    44Name1, Name2, Name3, Name4 Name1, Name2, Name3, Name4,
  4. builder ← (empty)

    11}12System.out.println(namesName1, Name2, Name3, Name4, Name5);1314StringBuilder builder→ (empty) = new StringBuilder();15for (int i = 1; i <= count; i++) {
    outputName1, Name2, Name3, Name4, Name5
  5. for (int i = 1; i <= count; i++)

    pass 1 of 5
    14StringBuilder builder = new StringBuilder();15for (int i1 = 1; i <= count5; i++) {16    builder.append("Name").append(i1);17    if (i < count) {
    All 5 passes — pass 1 is the card above
    passi
    11
    22
    33
    44
    55
  6. if (i < count)

    pass 1 of 4
    16builder.append("Name").append(i);17if (i1 < count5) {18    builder.append(", ");19}
    All 4 passes — pass 1 is the card above
    passi
    11
    22
    33
    44
  7. System.out.println(builder.toString());

    20    }21    System.out.println(builder.toString());22}
    outputName1, Name2, Name3, Name4, Name5
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.

example
Basics.java
Replay: real traced execution (multi-file project)
// StringBuilder basics

public class Basics {

    public static void main(String[] args) {
        // Create empty StringBuilder
        String first = "Hello";
        String second = "World";
        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 = "Goodbye";
        String second = "World";
        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 = "Hello";
        String second = "Java";
        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);
    }

}
  1. first ← Hello, second ← World, sb1 ← (empty), sb2 ← Java, sb3 ← (empty)

    5public static void main(String[] args) {6    // Create empty StringBuilder7    String first→ Hello = "Hello"; //@first="Hello", "Goodbye"8    String second→ World = "World"; //@second="World", "Java"9    StringBuilder sb1→ (empty) = new StringBuilder();10    sb1.append(firstHello);11    sb1.append(" ");12    sb1.append(secondWorld);13    System.out.println(sb1.toString());1415    // Create with initial string16    StringBuilder sb2→ Java = new StringBuilder("Java");17    System.out.println(sb2Java);1819    // Create with initial capacity20    StringBuilder sb3→ (empty) = new StringBuilder(50);21    sb3.append("Efficient");22    System.out.println("Length: " + sb3.length());23    System.out.println("Capacity: " + sb3.capacity());2425    // Append different types26    StringBuilder sb4→ (empty) = new StringBuilder();27    sb4.append("Age: ");28    sb4.append(25);29    sb4.append(", Score: ");30    sb4.append(95.5);31    sb4.append(", Active: ");32    sb4.append(true);33    System.out.println(sb4Age: 25, Score: 95.5, Active: true);34}
    outputHello World
    Java
    Length: 9
    Capacity: 50
    Age: 25, Score: 95.5, Active: true
  1. first ← Goodbye, second ← World, sb1 ← (empty), sb2 ← Java, sb3 ← (empty)

    5public static void main(String[] args) {6    // Create empty StringBuilder7    String first→ Goodbye = "Goodbye";8    String second→ World = "World";9    StringBuilder sb1→ (empty) = new StringBuilder();10    sb1.append(firstGoodbye);11    sb1.append(" ");12    sb1.append(secondWorld);13    System.out.println(sb1.toString());1415    // Create with initial string16    StringBuilder sb2→ Java = new StringBuilder("Java");17    System.out.println(sb2Java);1819    // Create with initial capacity20    StringBuilder sb3→ (empty) = new StringBuilder(50);21    sb3.append("Efficient");22    System.out.println("Length: " + sb3.length());23    System.out.println("Capacity: " + sb3.capacity());2425    // Append different types26    StringBuilder sb4→ (empty) = new StringBuilder();27    sb4.append("Age: ");28    sb4.append(25);29    sb4.append(", Score: ");30    sb4.append(95.5);31    sb4.append(", Active: ");32    sb4.append(true);33    System.out.println(sb4Age: 25, Score: 95.5, Active: true);34}
    outputGoodbye World
    Java
    Length: 9
    Capacity: 50
    Age: 25, Score: 95.5, Active: true
  1. first ← Hello, second ← Java, sb1 ← (empty), sb2 ← Java, sb3 ← (empty)

    5public static void main(String[] args) {6    // Create empty StringBuilder7    String first→ Hello = "Hello";8    String second→ Java = "Java";9    StringBuilder sb1→ (empty) = new StringBuilder();10    sb1.append(firstHello);11    sb1.append(" ");12    sb1.append(secondJava);13    System.out.println(sb1.toString());1415    // Create with initial string16    StringBuilder sb2→ Java = new StringBuilder("Java");17    System.out.println(sb2Java);1819    // Create with initial capacity20    StringBuilder sb3→ (empty) = new StringBuilder(50);21    sb3.append("Efficient");22    System.out.println("Length: " + sb3.length());23    System.out.println("Capacity: " + sb3.capacity());2425    // Append different types26    StringBuilder sb4→ (empty) = new StringBuilder();27    sb4.append("Age: ");28    sb4.append(25);29    sb4.append(", Score: ");30    sb4.append(95.5);31    sb4.append(", Active: ");32    sb4.append(true);33    System.out.println(sb4Age: 25, Score: 95.5, Active: true);34}
    outputHello Java
    Java
    Length: 9
    Capacity: 50
    Age: 25, Score: 95.5, Active: true
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
Replay: real traced execution (multi-file project)
// 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
    }

}
  1. sb1 ← Hello World, sb2 ← Java, sb3 ← Start, sb4 ← Hello Beautiful World

    5public static void main(String[] args) {6    // Insert7    StringBuilder sb1→ Hello World = new StringBuilder("Hello World");8    sb1.insert(6, "Beautiful ");9    System.out.println(sb1Hello Beautiful World);  // Hello Beautiful World1011    // Insert at beginning12    StringBuilder sb2→ Java = new StringBuilder("Java");13    sb2.insert(0, "I love ");14    System.out.println(sb2I love Java);  // I love Java1516    // Insert at end (same as append)17    StringBuilder sb3→ Start = new StringBuilder("Start");18    sb3.insert(sb3.length(), " End");19    System.out.println(sb3Start End);  // Start End2021    // Delete range22    StringBuilder sb4→ Hello Beautiful World = new StringBuilder("Hello Beautiful World");23    sb4.delete(6, 16);  // Remove "Beautiful "24    System.out.println(sb4Hello World);  // Hello World2526    // Delete single character27    StringBuilder sb5→ Helllo = new StringBuilder("Helllo");28    sb5.deleteCharAt(3);  // Remove extra 'l'29    System.out.println(sb5Hello);  // Hello3031    // Replace32    StringBuilder sb6→ Hello World = new StringBuilder("Hello World");33    sb6.replace(6, 11, "Java");34    System.out.println(sb6Hello Java);  // Hello Java35}
    outputHello Beautiful World
    I love Java
    Start End
    Hello World
    Hello
    Hello Java

Method Chaining

Chaining.java
Replay: real traced execution (multi-file project)
// 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);
    }

}
  1. sb ← (empty), sentence ← The quick brown fox, result ← Count: 10, Value: 3.14

    5public static void main(String[] args) {6    // Method chaining7    StringBuilder sb→ (empty) = new StringBuilder();8    sb.append("First")9      .append(" ")10      .append("Second")11      .append(" ")12      .append("Third");13    System.out.println(sbFirst Second Third);1415    // Build a sentence16    String sentence→ The quick brown fox = new StringBuilder()17        .append("The")18        .append(" quick")19        .append(" brown")20        .append(" fox")21        .toString();22    System.out.println(sentenceThe quick brown fox);2324    // Mix different operations25    String result→ Count: 10, Value: 3.14 = new StringBuilder()26        .append("Count: ")27        .append(10)28        .append(", ")29        .append("Value: ")30        .append(3.14)31        .toString();32    System.out.println(resultCount: 10, Value: 3.14);3334    // Build CSV line35    String csv→ John,30,Engineer,75000 = new StringBuilder()36        .append("John")37        .append(",")38        .append(30)39        .append(",")40        .append("Engineer")41        .append(",")42        .append(75000)43        .toString();44    System.out.println(csvJohn,30,Engineer,75000);45}
    outputFirst Second Third
    The quick brown fox
    Count: 10, Value: 3.14
    John,30,Engineer,75000
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.

word
Reverse.java
Replay: real traced execution (multi-file project)
// 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 = "racecar";
        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 = "level";
        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 = "java";
        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
    }

}
  1. sb1 ← Hello, word ← racecar, sb2 ← racecar, isPalindrome ← true

    5public static void main(String[] args) {6    // Reverse string7    StringBuilder sb1→ Hello = new StringBuilder("Hello");8    sb1.reverse();9    System.out.println(sb1olleH);  // olleH1011    // Check palindrome12    String word→ racecar = "racecar"; //@word="racecar", "level", "java"13    StringBuilder sb2→ racecar = new StringBuilder(word);14    boolean isPalindrome→ true = word.equals(sb2.reverse().toString());15    System.out.println(wordracecar + " is palindrome: " + isPalindrometrue);1617    // Set character at index18    StringBuilder sb3→ Hello = new StringBuilder("Hello");19    sb3.setCharAt(0, 'J');20    System.out.println(sb3Jello);  // Jello2122    // Set length (truncate or pad)23    StringBuilder sb4→ Hello = new StringBuilder("Hello");24    sb4.setLength(3);25    System.out.println(sb4Hel);  // Hel2627    StringBuilder sb5→ Hi = new StringBuilder("Hi");28    sb5.setLength(5);  // Pads with null chars29    System.out.println("Length: " + sb5.length());3031    // Substring32    StringBuilder sb6→ Hello World = new StringBuilder("Hello World");33    String sub→ World = sb6.substring(6, 11);34    System.out.println(subWorld);  // World35}
    outputolleH
    racecar is palindrome: true
    Jello
    Hel
    Length: 5
    World
  1. sb1 ← Hello, word ← level, sb2 ← level, isPalindrome ← true, sb3 ← Hello

    5public static void main(String[] args) {6    // Reverse string7    StringBuilder sb1→ Hello = new StringBuilder("Hello");8    sb1.reverse();9    System.out.println(sb1olleH);  // olleH1011    // Check palindrome12    String word→ level = "level";13    StringBuilder sb2→ level = new StringBuilder(word);14    boolean isPalindrome→ true = word.equals(sb2.reverse().toString());15    System.out.println(wordlevel + " is palindrome: " + isPalindrometrue);1617    // Set character at index18    StringBuilder sb3→ Hello = new StringBuilder("Hello");19    sb3.setCharAt(0, 'J');20    System.out.println(sb3Jello);  // Jello2122    // Set length (truncate or pad)23    StringBuilder sb4→ Hello = new StringBuilder("Hello");24    sb4.setLength(3);25    System.out.println(sb4Hel);  // Hel2627    StringBuilder sb5→ Hi = new StringBuilder("Hi");28    sb5.setLength(5);  // Pads with null chars29    System.out.println("Length: " + sb5.length());3031    // Substring32    StringBuilder sb6→ Hello World = new StringBuilder("Hello World");33    String sub→ World = sb6.substring(6, 11);34    System.out.println(subWorld);  // World35}
    outputolleH
    level is palindrome: true
    Jello
    Hel
    Length: 5
    World
  1. sb1 ← Hello, word ← java, sb2 ← java, isPalindrome ← false, sb3 ← Hello

    5public static void main(String[] args) {6    // Reverse string7    StringBuilder sb1→ Hello = new StringBuilder("Hello");8    sb1.reverse();9    System.out.println(sb1olleH);  // olleH1011    // Check palindrome12    String word→ java = "java";13    StringBuilder sb2→ java = new StringBuilder(word);14    boolean isPalindrome→ false = word.equals(sb2.reverse().toString());15    System.out.println(wordjava + " is palindrome: " + isPalindromefalse);1617    // Set character at index18    StringBuilder sb3→ Hello = new StringBuilder("Hello");19    sb3.setCharAt(0, 'J');20    System.out.println(sb3Jello);  // Jello2122    // Set length (truncate or pad)23    StringBuilder sb4→ Hello = new StringBuilder("Hello");24    sb4.setLength(3);25    System.out.println(sb4Hel);  // Hel2627    StringBuilder sb5→ Hi = new StringBuilder("Hi");28    sb5.setLength(5);  // Pads with null chars29    System.out.println("Length: " + sb5.length());3031    // Substring32    StringBuilder sb6→ Hello World = new StringBuilder("Hello World");33    String sub→ World = sb6.substring(6, 11);34    System.out.println(subWorld);  // World35}
    outputolleH
    java is palindrome: false
    Jello
    Hel
    Length: 5
    World

Practical Use

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

Practical.java
Replay: real traced execution (multi-file project)
// 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"));
    }

}
  1. public static void main(String[] args)

    60public static void main(String[] args) {61    // Build HTML table62    String[][] tableData = {63        {"Name", "Age", "City"},64        {"Alice", "25", "New York"},65        {"Bob", "30", "London"},66        {"Charlie", "35", "Paris"}67    };6869    System.out.println(buildTable(tableData));
  2. html ← (empty)

    5public static String buildTable(String[][] data) {6    StringBuilder html→ (empty) = new StringBuilder();78    html.append("<table>\n");
  3. if (data.length > 0)

    10// Header row11if (data.length4 > 0) {12    html.append("  <thead>\n    <tr>");13    for (String header : data[0]) {
  4. for (String header : data[0])

    pass 1 of 3
    12html.append("  <thead>\n    <tr>");13for (String headerName : data[0]) {14    html.append("<th>").append(headerName).append("</th>");15}
    All 3 passes — pass 1 is the card above
    passheader
    1Name
    2Age
    3City
  5. html.append("</tr> </thead> ");

    15    }16    html.append("</tr>\n  </thead>\n");17}
  6. html.append(" <tbody> ");

    19// Data rows20html.append("  <tbody>\n");21for (int i = 1; i < data.length; i++) {
  7. for (int i = 1; i < data.length; i++)

    pass 1 of 3
    20html.append("  <tbody>\n");21for (int i1 = 1; i < data.length4; i++) {22    html.append("    <tr>");23    for (String cell : data[i]) {
    All 3 passes — pass 1 is the card above
    passi
    11
    22
    33
  8. for (String cell : data[i])

    pass 1 of 9
    22html.append("    <tr>");23for (String cellAlice : data[i]) {24    html.append("<td>").append(cellAlice).append("</td>");25}
    All 9 passes — pass 1 is the card above
    passcelli
    1Alice1
    2251
    3New York1
    4Bob2
    5302
    6London2
    7Charlie3
    8353
    9Paris3
  9. html.append("</tr> ");

    25    }26    html.append("</tr>\n");27}
  10. html.append("</tr> ");

    25    }26    html.append("</tr>\n");27}
  11. html.append("</tr> ");

    25    }26    html.append("</tr>\n");27}
  12. html.append(" </tbody> ");

    27    }28    html.append("  </tbody>\n");2930    html.append("</table>");3132    return html.toString();33}
  13. System.out.println(buildTable(tableData));

    69System.out.println(buildTable(tableData));7071// Build SQL queries72System.out.println("\n" + buildSelectQuery("users", new String[0], null));73System.out.println(buildSelectQuery("users", new String[]{"name", "email"}, null));
    output<table>
      <thead>
        <tr><th>Name</th><th>Age</th><th>City</th></tr>
      </thead>
      <tbody>
        <tr><td>Alice</td><td>25</td><td>New York</td></tr>
        <tr><td>Bob</td><td>30</td><td>London</td></tr>
        <tr><td>Charlie</td><td>35</td><td>Paris</td></tr>
      </tbody>
    </table>
  14. sql ← (empty)

    pass 1 of 3
    35public static String buildSelectQuery(String tableusers, String[] columns, String conditionnull) {36    StringBuilder sql→ (empty) = new StringBuilder();3738    sql.append("SELECT ");
    All 3 passes — pass 1 is the card above
    passconditioncolumns.lengthisql
    1null0(empty)
    2null1(empty)
    3age > 25(empty)
  15. if (columns.length == 0)

    40if (columns.length0 == 0) {41    sql.append("*");42} else {
  16. sql.append(" FROM ").append(table);

    49    sql.append(" FROM ").append(tableusers);5051    if (condition != null && !condition.isEmpty()) {52        sql.append(" WHERE ").append(condition);53    }5455    sql.append(";");5657    return sql.toString();58}
  17. System.out.println(" " + buildSelectQuery("users", new String[0], null…

    71// Build SQL queries72System.out.println("\n" + buildSelectQuery("users", new String[0], null));73System.out.println(buildSelectQuery("users", new String[]{"name", "email"}, null));74System.out.println(buildSelectQuery("users", new String[]{"*"}, "age > 25"));
    output
    SELECT * FROM users;
  18. for (int i = 0; i < columns.length; i++)

    pass 1 of 3
    42} else {43    for (int i0 = 0; i < columns.length2; i++) {44        if (i > 0) sql.append(", ");45        sql.append(columns[i]name);46    }
    All 3 passes — pass 1 is the card above
    passicolumns.lengthcolumns[i]
    102name
    212
    301*
  19. if (i > 0)

    43for (int i = 0; i < columns.length; i++) {44    if (i1 > 0) sql.append(", ");45    sql.append(columns[i]);
  20. sql.append(columns[i]);

    44    if (i > 0) sql.append(", ");45    sql.append(columns[i]email);46}
    values this step1i
  21. sql.append(" FROM ").append(table);

    49    sql.append(" FROM ").append(tableusers);5051    if (condition != null && !condition.isEmpty()) {52        sql.append(" WHERE ").append(condition);53    }5455    sql.append(";");5657    return sql.toString();58}
  22. System.out.println(buildSelectQuery("users", new String[]{"name", "ema…

    72    System.out.println("\n" + buildSelectQuery("users", new String[0], null));73    System.out.println(buildSelectQuery("users", new String[]{"name", "email"}, null));74    System.out.println(buildSelectQuery("users", new String[]{"*"}, "age > 25"));75}
    outputSELECT name, email FROM users;
  23. sql.append(" FROM ").append(table);

    49sql.append(" FROM ").append(tableusers);
  24. if (condition != null && !condition.isEmpty())

    51if (conditionage > 25 != null && !condition.isEmpty()) {52    sql.append(" WHERE ").append(conditionage > 25);53}
  25. sql.append(";");

    55    sql.append(";");5657    return sql.toString();58}
  26. System.out.println(buildSelectQuery("users", new String[]{"*"}, "age >…

    73    System.out.println(buildSelectQuery("users", new String[]{"name", "email"}, null));74    System.out.println(buildSelectQuery("users", new String[]{"*"}, "age > 25"));75}
    outputSELECT * FROM users WHERE age > 25;

Exercise: Practical.java

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