应使用stringbuilder替代string循环拼接,因其可变且避免频繁对象创建;需预估容量、循环外创建、最后调用tostring(),并优先选用string.join等高层api。

直接用 String 在循环里拼接(比如 s += "x")会严重拖慢性能,核心原因是 String 不可变——每次拼接都新建对象,1000 次循环就产生 1000 个临时字符串,触发大量 GC 和内存分配。真正高效的做法是换掉它,而不是修修补补。
用 StringBuilder 替代 + 拼接
这是最直接、最常用的解法。StringBuilder 是可变的,内部用 char[] 缓冲区追加内容,不生成中间字符串。
- 循环外创建实例,不要在循环体内 new:避免重复构造开销和默认容量(16)带来的频繁扩容
- append 基本类型(如
int、boolean)时,直接写sb.append(i),不用String.valueOf(i)—— 少一次装箱和对象创建 - 单线程场景下,一律选 StringBuilder;只有多个线程共用同一个缓冲区时,才考虑 StringBuffer(但更推荐每个线程独立实例)
预估并设置初始容量
默认容量太小,数据一多就扩容:每次扩容要申请新数组、复制旧内容,代价叠加。比如拼接 500 条日志,每条平均 60 字符,加上分隔符约需 32000 字符,就该写 new StringBuilder(32000)。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 估算公式:基础长度 + 预期总字符数 + 10% 左右余量
- 不确定精确值也没关系,宁可略大一点,也比反复扩容强
只在最后调用一次 toString()
toString() 是“快照”操作,会完整复制当前内部数组。如果写在循环里,等于每轮都做一次全量拷贝,彻底废掉 StringBuilder 的优势。
- 所有 append 完成后再调用
sb.toString() - 调试时想看中间结果,可用
sb.length()或sb.substring(0, Math.min(100, sb.length())),不触发复制
优先考虑更高层的替代方案
如果拼接的是已有集合或数组,别手动写循环,JDK 提供了更安全、语义更清晰的工具:
-
String.join(",", list):简洁,自动处理 null(转为空字符串) -
StringJoiner:支持前缀、分隔符、后缀,适合构建带格式的字符串(如 JSON 片段、SQL IN 列表) -
list.stream().collect(Collectors.joining(",")):函数式风格,底层仍用 StringBuilder,但逻辑封装更稳
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










