优化 stringbuilder 拼接需预估容量、链式 append、避免 + 和 tostring()、直传基础类型、null 预处理、循环复用实例并 setlength(0) 清空。

用 StringBuilder.append() 优化长文本拼接,核心不是“用了 StringBuilder”,而是避开隐式开销、控制内存行为、让每次追加都落在可预测的路径上。算力损耗主要来自频繁对象分配、数组复制、字符串固化和类型转换——这些都能通过几条具体操作压下来。
初始化容量要预估,别靠默认值硬扛
默认构造的 StringBuilder 初始容量只有 16,一旦超限就扩容:新容量 = 旧容量 × 2 + 2。拼接百万字符时,可能触发十几次扩容,每次都要复制已有内容,CPU 和内存带宽全花在搬数据上。
- 粗略估算总长度:把所有待拼内容的字符数加起来,再加上传统分隔符(如逗号、换行)的长度
- 留 10%~20% 余量更稳妥,比如预计 85 万字符,就写
new StringBuilder(1_000_000) - 完全无法估算时,至少设为
new StringBuilder(4096)或64 * 1024,比 16 强太多
append 要链式调用,别掺杂 + 或 toString()
每调一次 + 或 toString(),就等于主动触发一次字符串创建和内存拷贝。尤其在循环里边拼边转,性能会跌回原始水平。
- 所有片段单独 append:不要写
sb.append(item + ", "),而要拆成sb.append(item).append(", ") - 整个拼接完成前,只调一次
toString(),且仅用于最终输出 - 调试时想看中间结果?用
sb.length()或sb.substring(0, Math.min(100, sb.length())),别反复 toString()
类型直传,绕过 String.valueOf() 和 null 陷阱
StringBuilder 的 append 方法重载丰富,直接传 int、boolean、char 等基础类型,JVM 会走高效路径;若先转成字符串再传,就多一次堆分配和 GC 压力。
- 拼数字优先用
append(123),而不是append(String.valueOf(123)) - 遇到可能为 null 的变量,提前处理:
sb.append(obj == null ? "" : obj.toString())或用Objects.toString(obj, "") - 避免在 append() 参数里写复杂表达式,比如
sb.append(getName().trim().toUpperCase())——提前算好再传
循环内复用实例,用 setLength(0) 清空而非重建
高频拼接场景(如日志组装、模板渲染),在循环外创建 StringBuilder,循环内用 setLength(0) 重置,能复用底层数组,省掉 new 和 GC 开销。
- 不要写
for (...) { new StringBuilder().append(...).toString(); } - 推荐模式:
StringBuilder sb = new StringBuilder(2048); for (...) { sb.setLength(0); sb.append(...); String s = sb.toString(); } - 注意:StringBuilder 不是线程安全的,多线程必须各自持有一个实例











