stringbuilder拼接超长字符串的关键是预估容量、避免重复扩容、及时复用;应初始化时指定足够容量,避免循环中频繁tostring(),优先使用append(),边拼边写或分块处理以防oom。

直接用 StringBuilder 拼接超长字符串时,关键不是“能不能拼”,而是“怎么拼才不慢、不崩、不浪费内存”。核心在于预估容量、避免重复扩容、及时复用。
初始化时指定足够容量
默认构造的 StringBuilder 初始容量是 16。如果最终要拼出百万字符,反复扩容(每次约翻倍)会触发多次数组复制,拖慢速度,还可能产生大量临时对象。应尽量在创建时就预估总长度。
- 能算出大致长度时,直接传入:
new StringBuilder(2_000_000) - 不确定但有上限,按上限设:比如日志行平均 200 字符 × 10 万行 → 至少 20MB,设
20_000_000 - 纯动态场景(如读流拼接),可先用
new StringBuilder(8192)起步,后续再调ensureCapacity()
避免在循环内频繁 toString() 或创建新实例
每调一次 toString() 都会新建一个 String 对象,内容完整复制。若在循环中反复调用,等于把整个拼接过程复制 N 次,内存和时间都爆炸。
- 只在最终需要结果时调一次
toString() - 不要写成:
for (...) { sb.append(...).toString(); } - 也不要为每个子片段单独 new 一个
StringBuilder,优先复用同一个实例(注意线程安全)
合理使用 append,慎用 insert / delete / replace
append() 是最高效的操作,内部只是拷贝字节数组。而 insert()、delete()、replace() 需要移动后续字符,长度越大开销越明显。
- 想在开头加内容?改用
insert(0, ...)前先评估代价;更推荐反向构建 + 最后reverse() - 需删中间段?考虑是否能用
setLength(0)清空重用,而非删了再拼 - 替换固定位置内容?若只是覆盖部分字符,可用
setCharAt(),比replace()快得多
超大字符串写入文件或网络时,别全 load 到内存
拼出几 GB 的字符串再一次性写入,极易 OOM。即使堆够大,GC 压力也极高。
- 边拼边写:用
Writer或OutputStream,每次append()后立即write() - 分块处理:每拼够 1MB 就 flush 一次,再
setLength(0)复用 - 真需要完整字符串?确认业务是否真的必须 —— 很多场景用
CharSequence或流式处理更合适
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











