# Summary StringBuilder 的核心优化就是**预分配容量**机制: 大部分 append 操作都是直接写入预留空间,避免了频繁的内存分配和复制。 # Cues # Notes ## 工作原理 1. **初始容量分配** - StringBuilder 创建时会分配一个字符数组(通常默认16个字符) - 这个数组有预留空间,不是刚好贴合当前字符串长度 2. **append 时的行为** - 如果预留空间足够:直接把新字符写入数组的下一个位置,O(1)操作 - 如果空间不够:才会扩容(通常是当前容量的2倍),然后复制 ## 对比普通字符串拼接 ```java // 普通字符串拼接 - 每次都创建新对象 String s = "Hello"; s = s + " World"; // 创建新String对象,复制"Hello",再加" World" s = s + "!"; // 又创建新对象,复制"Hello World",再加"!" // StringBuilder - 利用预留空间 StringBuilder sb = new StringBuilder(); // 预分配16个字符空间 sb.append("Hello"); // 直接写入,还剩11个空间 sb.append(" World"); // 直接写入,还剩5个空间 sb.append("!"); // 直接写入,无需复制 ``` ## 具体例子 ```java StringBuilder sb = new StringBuilder(20); // 预分配20个字符的容量 // 内部数组: [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] sb.append("Hello"); // 长度5,容量20 // 内部数组: [H, e, l, l, o, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] sb.append(" World"); // 长度11,容量20,直接append无需复制 // 内部数组: [H, e, l, l, o, , W, o, r, l, d, _, _, _, _, _, _, _, _, _] ``` 这就是为什么 StringBuilder 在大量字符串拼接时效率高得多 - 大部分 append 操作都是直接写入预留空间,避免了频繁的内存分配和复制。