stringbuilder的append方法高性能源于复用内部char数组、避免频繁创建对象及智能扩容策略;string因不可变性每次拼接均生成新对象,而stringbuilder仅在必要时扩容,且推荐预设容量、最后统一tostring,并优先选用非同步的stringbuilder而非stringbuffer。

StringBuilder 的 append 方法之所以高性能,核心在于它避免了频繁创建新字符串对象,复用内部字符数组,并通过扩容策略平衡空间与效率。
底层不产生新对象,直接修改内部 char 数组
String 是不可变的,每次拼接都会生成新对象,而 StringBuilder 内部维护一个可变的 char 数组(value)。调用 append 时,只是把新内容拷贝到这个数组的末尾,不创建新字符串对象。只有在容量不足时才触发扩容,而非每次调用都分配内存。
- 例如:
sb.append("a").append("b").append("c")只操作同一个 char 数组,最终只生成一次 String(如调用 toString() 时) - 对比 String:
s = s + "a" + "b" + "c"至少创建 3 个中间 String 对象
预设初始容量,减少扩容次数
char 数组扩容需复制原有数据,是性能损耗点。如果知道大致拼接长度,用带 capacity 参数的构造函数提前分配足够空间,能显著减少甚至避免扩容。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 推荐写法:
new StringBuilder(128)或new StringBuilder(expectedLength) - 默认容量是 16,若拼接结果远超此值(比如拼接 1000 字符),会多次扩容(16→34→70→142→286…),带来额外复制开销
连续 append 比反复 toString() 更高效
不要在循环中边拼边转成 String,例如:result += sb.toString() 或 list.add(sb.toString()) 前反复调用 toString()。这会每次新建 String 对象,抵消 StringBuilder 的优势。
- 正确做法:所有拼接完成后,仅在最后调用一次
sb.toString() - 错误模式示例:
for (String s : list) { sb.append(s); strings.add(sb.toString()); }→ 每次都生成新 String,且后续 append 还要再复制
注意线程安全取舍:不用 StringBuffer
除非多线程共享同一实例,否则别用 StringBuffer。它的 append 方法加了 synchronized,带来无谓同步开销。单线程下 StringBuilder 的 append 完全无锁,吞吐更高。
- 绝大多数场景(如方法内局部变量拼接)用 StringBuilder 即可
- 若真需线程安全,优先考虑重构为无共享状态,或使用 StringJoiner / List.join 等更现代方案
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










