循环拼接字符串应使用stringbuilder而非+,因string不可变会导致大量临时对象和频繁gc;需循环外初始化、循环内append、最后tostring,预估容量可提升性能。

在循环中拼接字符串,别用+,直接上StringBuilder——这是Java性能优化里最常踩坑、也最容易见效的一环。
为什么循环里不能用+拼接?
String是不可变的。每次result += "item" + i,JVM都会隐式创建一个StringBuilder→append→toString,生成一个新String对象。循环1万次,就可能产生上万个短命对象,堆内存猛涨,Young GC频繁触发。
而StringBuilder内部维护一个可变的字符数组,append()只是往末尾填数据,扩容也按需进行(默认16,不够时翻倍),没有中间对象开销。
正确写法:循环外建、循环内追加、最后转字符串
- ✅ 在
for循环之前初始化StringBuilder,不要放在循环体内 - ✅ 复用同一个实例,反复调用
append(),支持字符串、数字、布尔等多种类型 - ✅ 循环结束后,只调用一次
toString()获取最终结果——这步不能漏,也不能提前调
示例:
StringBuilder sb = new StringBuilder(2048);
for (String s : list) {
sb.append("ID: ").append(s).append("\n");
}
String output = sb.toString();
提升效率的关键细节
- 预估容量:知道大概长度就设初值,比如拼接500条日志、每条平均60字符,可用
new StringBuilder(500 * 60 + 1000),减少数组复制 - 避免隐式装箱:拼接整数时用
append(i),别写append(String.valueOf(i)) - 带分隔符?优先用
StringJoiner(Java 8+),或手动控制:先全拼,再用deleteCharAt()或substring()去多余符号 - 要多次复用?用
sb.setLength(0)清空,比新建更轻量;但确保无其他引用指向它
哪些情况不用硬套StringBuilder?
- 单行拼接,比如
"User " + user.getName() + " logged in":编译器会自动优化,代码更简洁 - 拼接次数≤3次,且内容简单:手动写
StringBuilder反而增加冗余 - 多线程共享同一实例:绝对禁止!应每个线程独立创建,或改用
StringBuffer(但有同步开销)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











