StringBuilder截取需原地修改:setLength()高效截断末尾;delete()组合或Java19+ deleteRange()裁剪区间;需新对象时用substring()构造,兼顾性能与可读性。

Java 中 StringBuilder 本身不提供返回新对象的“截取”方法,但可以通过原地修改实现高效子串提取——核心是避免创建中间 String 对象,尤其在处理大字符串或高频操作时优势明显。
用 setLength() 快速保留前 n 个字符
这是最轻量的方式,适用于只需截断末尾的场景。它直接调整内部长度字段,不复制数据,时间复杂度接近 O(1)。
- 调用 sb.setLength(n),n 必须满足 0 ≤ n ≤ sb.length(),否则抛出异常
- 操作后原 StringBuilder 内容被永久修改,比如
sb = new StringBuilder("hello world"); sb.setLength(5);结果为"hello" - 若需保留原始内容,应先复制:
new StringBuilder(sb)
用 delete() 精确裁剪任意区间
要保留中间某段(如索引 start 到 end-1),推荐组合两次 delete():先删开头,再删结尾。注意第二次删除的起始位置需基于当前长度计算。
- 稳妥写法:sb.delete(end, sb.length()).delete(0, start) —— 先删右半部分,再删左半部分,避免索引偏移问题
- 例如原串
"abcdefgh",保留 [2,6) 即 "cdef":sb.delete(6, 8).delete(0, 2) - Java 19+ 可用更清晰的 deleteRange(start, end),语义与 substring 一致,但仍是就地删除
需要新 StringBuilder 对象?优先用 substring + 构造器
如果逻辑上必须保留原对象、且对性能要求不是极端苛刻,可用 sb.substring(start, end) 获取 String,再传入 StringBuilder 构造器。
立即学习“Java免费学习笔记(深入)”;
-
new StringBuilder(sb.substring(start, end))比反复 delete() 更直观,也避免内部数组缩容抖动 - 该方式仍比纯 String.substring() 高效:StringBuilder 的 substring 底层用
System.arraycopy,不共享底层数组,无内存泄漏风险 - 适合中等规模字符串(如几 KB)或开发可读性优先的场景
避开常见陷阱
高性能的前提是正确使用。几个关键细节容易被忽略:
- 所有操作都是不可逆的,没有 undo;多线程下需同步,或改用 StringBuffer(但性能下降)
- 索引按 Unicode 码点数计算,不是字节数;含 emoji 或扩展汉字时,用
sb.codePointCount(0, sb.length())替代 length() 更安全 - 频繁 delete 后追加内容,内部数组可能未及时缩容,必要时调用 trimToSize() 释放冗余空间



















