应循环外初始化stringbuilder、预估并设置足够初始容量、仅在循环结束后调用一次tostring()、直接append基本类型、单线程用stringbuilder、多线程避免共享实例。

循环外初始化,避免重复创建
每次在循环体内 new StringBuilder(),等于每轮都新建对象、分配数组、触发默认容量(16)的初始开销。哪怕只拼接几十次,也可能因频繁扩容复制而拖慢速度。正确做法是把实例创建放在循环之前——一个对象复用全程,append 只往已有 char[] 里写,不产生中间对象。
预估并设置初始容量
默认容量太小,数据一多就扩容:每次扩容需申请新数组、拷贝旧内容,时间成本叠加。比如拼接 200 条日志,每条平均 80 字符,加上分隔符和前缀共约 18000 字符,直接写 new StringBuilder(18000) 能基本避免扩容。估算公式可参考:基础长度 + 预期总字符数 + 适量余量(如 10%)。
单次 toString(),禁止循环内调用
toString() 是“快照”操作,会复制当前内部数组生成新 String。若在循环里反复调用,等于每轮都做一次完整拷贝,彻底抵消 StringBuilder 的优势。必须等所有 append 完成后,只调用一次 sb.toString() 获取最终结果。中间若需调试,可用 sb.length() 或 sb.substring(0, Math.min(50, sb.length())) 查看片段,不触发全量复制。
注意类型与线程边界
拼接数字、布尔等基本类型时,直接 sb.append(i) 即可,无需 String.valueOf(i)——后者多一次装箱+对象创建。单线程场景一律用 StringBuilder;多线程共享同一实例时,不能简单换成 StringBuffer(同步开销大),更推荐每个线程独立创建,或用 ThreadLocal
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











