StringBuffer 是线程安全类
StringBuilder是非线程安全类,比 StringBuffer 要快。
StringBuffer 和StringBuilder 是AbstractStringBuilder的子类。
AbstractStringBuilder 内部有一个char数组,用于保存数据。
AbstractStringBuilder implements Appendable, CharSequence {
char[] value;//保存char
int count;//当前使用的长度
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
public int length() {//使用的长度
return count;
}
public int capacity() {//返回char数组的长度
return value.length;
}
//扩展数组容量
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);
}
//insert 相当于在数组中间插入,所以会重新构建数组
public AbstractStringBuilder insert(int offset, String str) {
if ((offset < 0) || (offset > length()))
throw new StringIndexOutOfBoundsException(offset);
if (str == null)
str = "null";
int len = str.length();
ensureCapacityInternal(count + len);
System.arraycopy(value, offset, value, offset + len, count - offset);
str.getChars(value, offset);
count += len;
return this;
}
}
StringBuffer 扩展了AbstractStringBuilder,并覆盖了父类方法,并且每一个方法都是synchronized的,所以它的线程安全的。
StringBuilder默认构建器设置数组大小为16.
public StringBuilder() {
super(16);
}
带有字符串参数的构建器将数组长度初始化为字符串长度+16.
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
设置数组大小的构建器:(如果能知道最终数组的大概长度,实例化时就设定好。 )
public StringBuilder(int capacity) {
super(capacity);
}
StringBuilder 有一个内部变量 count 用于计算当前添加了多少个字符,相当于游标,初始值为0。
新添加字符串时:count = count+添加字符串的长度。
中增加字符串时,如果count>数组长度, StringBuilder 会自动扩充数组,扩充方式新建数组,新建数组长度为(原数组长度+1)的2倍,如果还不够则长度取原数组长度+新增字符串长度:
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
setLength(int newLength) 方法:指定count(游标)值,当设定 newLength ==0 (count==0),即清空数组,可以重复利用。当 newLength>数组长度,调用 expandCapacity(newLength); 相当于扩度数组。