String 類別是不可變的,每次修改(拼接、替換、刪除)都會創建新對象,頻繁操作會產生大量臨時對象,增加 GC 壓力。StringBuffer 和 StringBuilder 解決了這個問題:它們代表可變字符序列,支持原地修改,不產生新對象。
| 特性 | StringBuffer | StringBuilder |
|---|---|---|
| 線程安全 | ✅ 所有公共方法加 synchronized | ❌ 非線程安全 |
| 性能 | 較低(鎖開銷) | 較高(無鎖) |
| 推出版本 | JDK 1.0 | JDK 5.0 |
| 適用場景 | 多線程環境下字符串操作 | 單線程或已同步環境(絕大多數情況) |
建議:現代開發中 95% 以上場景首選StringBuilder;僅在多線程共享字符串構建器時使用StringBuffer。
public class Test {
public static void main(String[] args) {
StringBuffer sBuffer = new StringBuffer(" test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer); // 輸出: test String Buffer
}
}
| 方法 | 說明 |
|---|---|
append(String s) | 追加字符串,返回 this(支持鏈式調用) |
insert(int offset, String s) | 在指定位置插入字符串 |
delete(int start, int end) | 刪除 [start, end) 區間字符 |
replace(int start, int end, String str) | 替換 [start, end) 區間為新字符串 |
reverse() | 反轉字符序列 |
| 方法 | 說明 |
|---|---|
charAt(int index) | 獲取指定索引字符 |
indexOf(String str) / lastIndexOf(String str) | 查找子字符串首次/最後出現位置 |
substring(int start) / substring(int start, int end) | 截取子字符串(返回新 String) |
length() | 返回字符長度 |
capacity() | 返回當前容量(底層數組大小) |
ensureCapacity(int min) | 確保最小容量 |
setCharAt(int index, char ch) | 修改指定位置字符 |
setLength(int newLength) | 設置字符序列長度 |
toString() | 轉為不可變 String |
getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):複製字符到目標數組subSequence(int start, int end):返回 CharSequence 子序列兩者底層均為 char[] 數組,默認初始容量 16。擴容策略:newCapacity = (oldCapacity + 1) * 2。頻繁擴容有性能損耗,預估大致長度時建議用構造函數指定初始容量:new StringBuilder(100)。
StringBuilder(性能最優)StringBuffer(線程安全)+ 優化為 StringBuilder.append(),但循環中手動創建 StringBuilder 更高效。掌握兩者異同與核心 API,能讓你在字符串處理場景下寫出高性能、無 Bug 的代碼。