用stringbuilder替代循环内字符串拼接可显著提升性能:循环外初始化、预设容量、链式append、线程隔离复用,避免临时对象与扩容开销。

用 StringBuilder 替代循环内的 += 或 + 拼接,核心是绕开 String 的不可变性——每次 + 都新建对象、触发 GC;而 StringBuilder 复用底层数组,append() 只是写入字符,时间复杂度从 O(n²) 降到 O(n),实测 5 万次拼接可从 800ms 压到 3ms。
循环外初始化,循环内只 append
别在循环体里 new StringBuilder。每次新建不仅浪费对象分配,还丢掉了缓冲区复用优势:
- ✅ 正确:循环前创建一次,循环中连续
append(),最后统一toString() - ❌ 错误:
for (...) { StringBuilder sb = new StringBuilder(); sb.append(...); }—— 等于没优化
预设合理初始容量,减少数组复制
默认容量仅 16,超出就扩容(旧容量 × 2 + 2),每次扩容都要复制整个数组。预估总长后显式指定容量,能大幅降低复制次数:
- 拼接 1000 条日志,每条平均 60 字符 →
new StringBuilder(64000)(留 10% 余量) - 完全不确定长度但数据量大 → 至少设
new StringBuilder(4096),比默认 16 更稳妥 - 避免用
ensureCapacity()补救,它只扩不缩,还多一次方法调用
链式调用 append,避开隐式转换
append() 返回自身,支持链式写法,且对基本类型有重载方法,直接写入字符序列,不经过 String.valueOf():
- ✅ 推荐:
sb.append("id=").append(userId).append(", active=").append(isActive) - ❌ 避免:
sb.append("id=" + userId)(先生成临时 String)或sb.append(String.valueOf(userId))(多一次对象创建) - 拼接
null会抛NullPointerException(JDK 8+),需提前判空或用Objects.toString(x, "")
复用实例与线程安全边界
单线程下复用比新建更轻量,但必须守住线程隔离底线:
- 方法内多次拼接?用
sb.setLength(0)清空,保留底层数组,比new快 - 线程池任务中?配合
ThreadLocal<stringbuilder></stringbuilder>,每个线程独享实例 - 绝对禁止
static共享或跨线程传同一实例——可能乱序、丢字符,甚至崩溃 - 真需多线程共享?改用
StringBuffer,但同步开销高 50%~100%,通常不如每个线程独立创建
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











