StringBuilder 扩容机制:
-
初始化容量:当创建一个新的
StringBuilder对象时,如果没有指定容量,它通常会有一个默认容量,通常是16个字符。 -
扩容过程:当
StringBuilder中的字符数达到当前容量时,就需要进行扩容。扩容的过程通常是将容量增加到当前容量的2倍加2,即新容量 = 当前容量 * 2 + 2。 -
内存分配:扩容时,会创建一个新的字符数组,其大小是新的容量,并将原数组的内容复制到新数组中。
-
性能影响:由于涉及到内存分配和数组复制,扩容是一个相对昂贵的操作。因此,如果预先知道字符串大概的长度,最好在创建
StringBuilder时就指定一个足够大的容量,以减少扩容操作的次数。
StringBuffer 扩容机制:
-
初始化容量:与
StringBuilder类似,StringBuffer也有一个默认容量,通常也是16个字符。 -
扩容过程:
StringBuffer的扩容过程与StringBuilder相同,也是将容量增加到当前容量的2倍加2。 -
线程安全:与
StringBuilder不同,StringBuffer的所有公共方法都是同步的,这意味着它是线程安全的。但是,这也导致了StringBuffer在单线程环境下性能不如StringBuilder。 -
内存分配和性能影响:与
StringBuilder一样,StringBuffer在扩容时也会进行内存分配和数组复制,对性能有影响。
总结:
StringBuilder和StringBuffer的扩容机制基本相同,都是将容量增加到当前容量的2倍加2。- 在使用这两个类时,如果可能,最好预先指定一个足够大的容量,以避免频繁扩容带来的性能开销。
- 选择
StringBuilder还是StringBuffer取决于是否需要线程安全。在单线程环境中,推荐使用StringBuilder,因为它更快;在多线程环境中,如果需要线程安全,则使用StringBuffer。
public class StringBuilderStringBuffer {
public static void main(String[] args) {
// StringBuilder 示例
StringBuilder sb = new StringBuilder();
int defaultCapacity = 16; // 默认容量
System.out.println("StringBuilder 默认容量: " + defaultCapacity);
// 添加字符直到扩容
for (int i = 0; i < defaultCapacity; i++) {
sb.append('a');
}
// 添加一个字符,触发扩容
sb.append('b');
// 新容量是原来的两倍加2
int newCapacity = (defaultCapacity * 2) + 2;
System.out.println("StringBuilder 扩容后容量: " + newCapacity);
// StringBuffer 示例
StringBuffer sbf = new StringBuffer();
// 默认容量也是16
System.out.println("StringBuffer 默认容量: " + defaultCapacity);
// 添加字符直到扩容
for (int i = 0; i < defaultCapacity; i++) {
sbf.append('a');
}
// 添加一个字符,触发扩容
sbf.append('b');
// 新容量也是原来的两倍加2
System.out.println("StringBuffer 扩容后容量: " + newCapacity);
}
}

String、StringBuilder、StringBuffer 如何使用?
String 的使用
String类在Java中用来表示不可变的字符序列。这意味着一旦创建了一个String对象,它的值就不能更改。
String str = "Hello";
str = str + " World"; // 实际上创建了一个新的String对象
System.out.println(str); // 输出 "Hello World"
StringBuilder 的使用
StringBuilder类是一个可变的字符序列,它提供了比String更高效的字符串修改方法。它不是线程安全的,适用于单线程环境。
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // 在原StringBuilder对象上追加字符
System.out.println(sb.toString()); // 输出 "Hello World"
StringBuilder通常用于以下场景:
- 当你需要频繁修改字符串时(例如,在循环中拼接字符串)。
- 当你处理大量数据时,因为它不会像
String那样创建多个临时对象。
StringBuffer 的使用
StringBuffer与StringBuilder非常相似,但是它是线程安全的,因为它的大多数方法都是同步的。这意味着在多线程环境中,StringBuffer可以安全地被多个线程共享和修改。
StringBuffer sbf = new StringBuffer("Hello");
sbf.append(" World"); // 在原StringBuffer对象上追加字符
System.out.println(sbf.toString()); // 输出 "Hello World"
总结
- 使用
String当你不需要修改字符串,或者只进行少量修改。 - 使用
StringBuilder当你处于单线程环境,并且需要频繁修改字符串。 - 使用
StringBuffer当你处于多线程环境,并且需要修改字符串。


被折叠的 条评论
为什么被折叠?



