Java StringBuilder

StringBuilder 是可變的字串類別,用於需要頻繁修改字串的情況,效能比直接使用 String 好。

為什麼需要 StringBuilder?

String 是不可變的,每次修改都會建立新物件:

// 效能差:每次 += 都建立新字串物件
String s = "";
for (int i = 0; i < 10000; i++) {
    s += i;  // 建立 10000 個中間物件
}

// 效能好:使用 StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append(i);  // 在同一個物件上操作
}
String result = sb.toString();

建立 StringBuilder

// 空的 StringBuilder(預設容量 16)
StringBuilder sb1 = new StringBuilder();

// 指定初始容量
StringBuilder sb2 = new StringBuilder(100);

// 從字串建立
StringBuilder sb3 = new StringBuilder("Hello");

常用方法

append()

在尾端添加內容:

StringBuilder sb = new StringBuilder();

sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.append(123);
sb.append(true);

System.out.println(sb.toString());  // "Hello World123true"

方法鏈 (Method Chaining)

String result = new StringBuilder()
    .append("Name: ")
    .append("Alice")
    .append(", Age: ")
    .append(25)
    .toString();

System.out.println(result);  // "Name: Alice, Age: 25"

insert()

在指定位置插入:

StringBuilder sb = new StringBuilder("Hello World");

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

sb.insert(0, ">>> ");
System.out.println(sb);  // ">>> Hello Java World"

delete() 和 deleteCharAt()

StringBuilder sb = new StringBuilder("Hello World");

// 刪除範圍
sb.delete(5, 11);  // 刪除索引 5 到 10
System.out.println(sb);  // "Hello"

// 刪除單一字元
sb.deleteCharAt(0);
System.out.println(sb);  // "ello"

replace()

StringBuilder sb = new StringBuilder("Hello World");

sb.replace(6, 11, "Java");
System.out.println(sb);  // "Hello Java"

reverse()

StringBuilder sb = new StringBuilder("Hello");

sb.reverse();
System.out.println(sb);  // "olleH"

substring()

StringBuilder sb = new StringBuilder("Hello World");

String sub = sb.substring(0, 5);
System.out.println(sub);  // "Hello"

setCharAt()

StringBuilder sb = new StringBuilder("Hello");

sb.setCharAt(0, 'J');
System.out.println(sb);  // "Jello"

length() 和 capacity()

StringBuilder sb = new StringBuilder("Hello");

System.out.println(sb.length());    // 5(字元數)
System.out.println(sb.capacity());  // 21(16 + 5,容量)

// 設定長度
sb.setLength(3);
System.out.println(sb);  // "Hel"

// 確保容量
sb.ensureCapacity(100);

StringBuilder vs StringBuffer

特性StringBuilderStringBuffer
執行緒安全
效能較快較慢
適用情境單執行緒多執行緒
// 單執行緒使用 StringBuilder
StringBuilder sb = new StringBuilder();

// 多執行緒使用 StringBuffer
StringBuffer sbf = new StringBuffer();

大多數情況下使用 StringBuilder 即可,只有在多執行緒共用時才需要 StringBuffer

實際應用

建立 SQL 語句

StringBuilder sql = new StringBuilder();
sql.append("SELECT * FROM users");
sql.append(" WHERE status = 'active'");
sql.append(" AND age > 18");
sql.append(" ORDER BY name");

System.out.println(sql);

建立 JSON

StringBuilder json = new StringBuilder();
json.append("{");
json.append("\"name\": \"Alice\",");
json.append("\"age\": 25,");
json.append("\"city\": \"Taipei\"");
json.append("}");

System.out.println(json);

建立 HTML

StringBuilder html = new StringBuilder();
html.append("<ul>\n");
for (String item : items) {
    html.append("  <li>").append(item).append("</li>\n");
}
html.append("</ul>");

反轉字串

String original = "Hello World";
String reversed = new StringBuilder(original).reverse().toString();
System.out.println(reversed);  // "dlroW olleH"

檢查回文

String s = "A man a plan a canal Panama";
String clean = s.replaceAll("[^a-zA-Z]", "").toLowerCase();
String reversed = new StringBuilder(clean).reverse().toString();

boolean isPalindrome = clean.equals(reversed);
System.out.println(isPalindrome);  // true

效能比較

int iterations = 100000;

// String(慢)
long start1 = System.currentTimeMillis();
String s = "";
for (int i = 0; i < iterations; i++) {
    s += "a";
}
System.out.println("String: " + (System.currentTimeMillis() - start1) + "ms");

// StringBuilder(快)
long start2 = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < iterations; i++) {
    sb.append("a");
}
System.out.println("StringBuilder: " + (System.currentTimeMillis() - start2) + "ms");

典型結果:

  • String: 數千毫秒
  • StringBuilder: 數毫秒

何時使用 StringBuilder

情況建議
簡單的字串連接(2-3 個)使用 +
迴圈中連接字串使用 StringBuilder
大量字串操作使用 StringBuilder
多執行緒環境使用 StringBuffer
連接陣列元素使用 String.join()