StringBuilder.ensureCapacity()
是性能优化的核心方法,用于主动扩容底层字符数组,避免自动扩容带来的性能损耗。特别适合预知数据量大小的场景。
1. 方法定义
public void ensureCapacity(int minimumCapacity)
- 参数:
minimumCapacity
:期望的最小容量(必须 ≥0)
- 返回值:无
- 扩容规则:
- 当前容量 < 参数值 → 扩容
- 当前容量 ≥ 参数值 → 无操作
- 新容量取
max(当前容量*2 + 2, minimumCapacity)
2. 功能说明
场景 | 扩容行为 |
---|---|
当前容量 16,请求容量 20 | 新容量 = max(16*2+2=34, 20) → 34 |
当前容量 30,请求容量 20 | 无操作(30>20) |
请求容量为负数 | 抛出 IllegalArgumentException |
3. 示例代码
public class EnsureCapacityExample {
public static void main(String[] args) {
// 初始容量16(默认)
StringBuilder sb = new StringBuilder();
System.out.println("初始容量: " + sb.capacity()); // 16
// 扩容到50
sb.ensureCapacity(50);
System.out.println("扩容后容量: " + sb.capacity()); // 50 (50 > 16*2+2=34)
// 尝试缩小容量(无效)
sb.ensureCapacity(10);
System.out.println("尝试缩容后: " + sb.capacity()); // 50(不变)
// 带数据扩容
StringBuilder data = new StringBuilder("Hello");
data.ensureCapacity(100);
System.out.println("带数据扩容: " + data.capacity()); // 100
System.out.println("内容保留: " + data); // "Hello"
}
}
4. 使用技巧
批量操作前预扩容:
StringBuilder sb = new StringBuilder(); List<String> words = Arrays.asList("apple", "banana", "cherry"); // 总长度约18 // 预扩容避免多次扩容 sb.ensureCapacity(20); // 直接扩容到20+ for (String word : words) { sb.append(word); }
精确计算容量:
int estimatedLength = 5000; sb.ensureCapacity(estimatedLength + 10); // 增加安全余量
与构造函数配合:
// 等效于 new StringBuilder(100) StringBuilder sb = new StringBuilder(); sb.ensureCapacity(100);
5. 常见错误与注意事项
误解容量与长度:
StringBuilder sb = new StringBuilder("Hi"); // 长度=2, 容量=18(16+2) sb.ensureCapacity(10); // 无操作(18>10)
负容量值:
sb.ensureCapacity(-1); // 抛出 IllegalArgumentException
过度扩容浪费内存:
// 错误:申请1GB内存 sb.ensureCapacity(1_000_000_000);
6. 最佳实践与性能优化
扩容成本对比: | 扩容策略 | 追加10,000字符耗时 | 说明 | |-------------------|-------------------|-------------------------| | 无预扩容 | ~1500μs | 多次扩容+数组复制 | |
ensureCapacity()
| ~200μs | 单次扩容,性能提升87% |内存效率优化:
// 根据数据特征动态扩容 if (sb.length() > sb.capacity() * 0.75) { sb.ensureCapacity(sb.capacity() * 2); // 按需扩容 }
超大文本处理:
// 处理1MB文本 StringBuilder sb = new StringBuilder(); sb.ensureCapacity(1_048_576); // 1024*1024 // ...文件读取/网络数据处理...
7. 总结
关键点 | 说明 |
---|---|
核心作用 | 主动控制扩容,减少自动扩容次数 |
扩容算法 | newCapacity = max(oldCapacity*2 + 2, minimumCapacity) |
性能收益 | 减少数组复制次数,尤其适合批量操作 |
容量 vs 长度 | 容量是数组大小,长度是实际字符数 |
内存权衡 | 过度扩容浪费内存,需平衡性能与资源 |
使用场景推荐:
- ✅ 已知最终长度的字符串构建(如文件读取)
- ✅ 循环追加大量数据
- ❌ 少量追加操作(默认扩容机制已足够高效)