String 物件不可變,每次修改都會產生新物件。頻繁字串操作時,應使用 StringBuffer 或 StringBuilder——它們內部維護可變字元陣列,避免大量中間物件產生。
| 特性 | StringBuffer | StringBuilder |
|---|---|---|
| 登場版本 | JDK 1.0 | JDK 1.5 |
| 執行緒安全 | 是(方法同步) | 否(非同步) |
| 效能 | 較低 | 較高(單執行緒下) |
| 適用場景 | 多執行緒環境共享字串緩衝區 | 單執行緒、高頻字串操作 |
建議: 單執行緒優先用 StringBuilder;多執行緒共享才用 StringBuffer。
StringBuffer sb = new StringBuffer("菜鳥教程官網:");
sb.append("www").append(".runoob").append(".com");
System.out.println(sb); // 菜鳥教程官網:www.runoob.com
| 方法 | 說明 |
|---|---|
append(String) | 追加字串(支援多型別重載) |
insert(offset, data) | 指定位置插入 |
delete(start, end) | 刪除子字串 [start, end) |
replace(start, end, str) | 替換子字串 |
reverse() | 反轉字元序列 |
| 方法 | 說明 |
|---|---|
charAt(index) | 取得指定索引字元 |
indexOf(str) / lastIndexOf(str) | 搜尋子字串 |
substring(start) / substring(start, end) | 取得子字串(返回 String) |
length() | 字元長度 |
capacity() | 當前容量(底層陣列大小) |
ensureCapacity(min) | 確保最小容量 |
setLength(newLength) | 設定長度(截斷或擴充以 '\0' 填充) |
setCharAt(index, ch) | 設定指定索引字元 |
toString() | 轉為 String 物件 |
API 幾乎一模一樣,僅移除 synchronized 關鍵字。直接替換類別名即可:
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World").reverse();
System.out.println(sb); // dlroW olleH
// 單執行緒追加 100萬次
long t1 = System.currentTimeMillis();
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < 1_000_000; i++) sbf.append("a");
System.out.println("StringBuffer: " + (System.currentTimeMillis() - t1) + "ms");
long t2 = System.currentTimeMillis();
StringBuilder sbl = new StringBuilder();
for (int i = 0; i < 1_000_000; i++) sbl.append("a");
System.out.println("StringBuilder: " + (System.currentTimeMillis() - t2) + "ms");
// 典型結果:StringBuilder 快 2-3 倍
(舊容量 + 1) * 2。new StringBuilder(100) 或 ensureCapacity() 預分配,減少擴充開銷。+,編譯器優化為 StringBuilder。StringBuilder(單執行緒)或 StringBuffer(多執行緒)。String 時呼叫 toString()。String.join()、Collectors.joining() 等現代 API,優先考慮。