// 單參數:從 beginIndex 到結尾
"unhappy".substring(2) // "happy"
"emptiness".substring(9) // ""
// 雙參數:[beginIndex, endIndex) 左閉右開
"hamburger".substring(4, 8) // "urge"
"smiles".substring(1, 5) // "mile"
// 實戰:去除前導斜線
String resource = "/api/users";
String stripped = resource.startsWith("/") ? resource.substring(1) : resource; // "api/users"
⚠️ Java 7+ 共享 char[] 底層陣列,`substring` 為 O(1) 但會保留原大字串記憶體。大量處理長字串時建議 `new String(str.substring(...))` 強制複製。
| 方法 | 說明 | 範例 |
|---|---|---|
| `charAt(int index)` | 取單一字元 | `"abc".charAt(1)` → `'b'` |
| `indexOf(String str)` / `lastIndexOf` | 搜尋位置,找不到回 -1 | `"ababa".indexOf("ba")` → `1` |
| `split(String regex)` | 正則分割 | `"a,b,c".split(",")` → `["a","b","c"]` |
| `replace(CharSequence, CharSequence)` | 字面替換 (非正則) | `"a.b".replace(".", "_")` → `"a_b"` |
| `replaceAll(String regex, String repl)` | 正則替換 | `"a1b2".replaceAll("\\d", "#")` → `"a#b#"` |
| `trim()` / `strip()` (Java 11) | 去除首尾空白 | `" hi ".strip()` → `"hi"` |
| `startsWith` / `endsWith` | 前綴/後綴判斷 | `"img.png".endsWith(".png")` → `true` |
| `valueOf(Object)` | 萬能轉字串,null 安全 | `String.valueOf(null)` → `"null"` |
| `format(String fmt, Object... args)` | 格式化 | `String.format("%,d", 10000)` → `"10,000"` |
| `join(CharSequence, CharSequence...)` (Java 8) | 連接 | `String.join("-", "2024","01","01")` → `"2024-01-01"` |
核心差異:`StringBuffer` 同步安全 (舊 API);`StringBuilder` 非同步、效能更高 (Java 5+ 推薦)。
StringBuilder sb = new StringBuilder(128); // 預估容量避免擴容
sb.append("user_").append(id).append("_").append(timestamp);
sb.insert(0, "prefix_"); // 指定位置插入
sb.delete(5, 10); // 刪除區間
sb.replace(0, 3, "NEW"); // 替換區間
sb.reverse(); // 反轉
String result = sb.toString(); // 最終轉 String
| 場景 | 推薦 | 原因 |
|---|---|---|
| 少量拼接、常數 | `+` / `String.concat()` | 編譯器優化為 `StringBuilder` |
| 迴圈/大量拼接 | `StringBuilder` | 避免產生大量中間 String 物件 |
| 多執行緒共享緩衝區 | `StringBuffer` | 方法同步保證執行緒安全 |
| 日誌/除錯訊息 | Slf4j 佔位符 `log.debug("user={}", name)` | 避免字串拼接開銷,延遲計算 |