StringBuilder
的底层是一个可变长度的字符数组 value
。这个数组用于存储字符串的字符数据。
核心字段:
class StringBuilder {
// 用于存储字符数据的数组
char[] value;
// 记录当前字符串的长度
int count;
// 初始容量为16
static final int DEFAULT_CAPACITY = 16;
}
StringBuilder
提供了多个构造方法,可以根据需要初始化字符数组的容量。
常用构造方法:
public StringBuilder() {
this(DEFAULT_CAPACITY); // 默认容量为16
}
public StringBuilder(int capacity) {
value = new char[capacity];
}
public StringBuilder(String str) {
value = new char[str.length() + DEFAULT_CAPACITY];
append(str);
}
append
方法append
方法是 StringBuilder
中最常用的方法之一,它用于在当前字符串的末尾追加字符或字符串。append
方法的实现包括两个主要步骤:检查是否需要扩容,并将新内容复制到 value
数组中。
append
方法的实现:
public StringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
步骤解析:
ensureCapacityInternal
方法用于检查当前字符数组的容量是否足够容纳新的字符,如果不够则进行扩容。getChars
方法将 str
中的字符复制到 value
数组的末尾位置。count
记录了当前字符串的长度,在追加新内容后更新它。StringBuilder
的扩容机制在 append
时起关键作用。如果当前字符数组的容量不足以容纳新追加的内容,StringBuilder
会自动扩容,通常会将容量扩大到原来的 2 倍左右。
扩容实现:
private void ensureCapacityInternal(int minimumCapacity) {
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) { // 溢出处理
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
步骤解析:
ensureCapacityInternal
方法判断当前数组容量是否足够。expandCapacity
方法计算扩容后的新容量,通常为当前容量的两倍加二,以应对数组增长需求。Arrays.copyOf
方法将原数组内容复制到新扩展的数组中。toString
方法StringBuilder
最终会通过 toString
方法将内容转换为不可变的 String
对象。
toString
方法的实现:
public String toString() {
return new String(value, 0, count);
}
步骤解析:
String
对象,将 StringBuilder
当前字符数组中的内容复制到新的 String
中。StringBuilder
通过一个可变的字符数组实现字符串的动态操作,append
等方法会根据需要自动扩容,并将新内容追加到数组中。StringBuilder
的设计保证了在频繁操作字符串的场景下具备较高的性能,尤其是在单线程环境中,不需要为线程安全付出额外的开销。