类定义
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence
StringBuilder 类被声明为 final,说明它不能再被继承。同时它继承了 AbstractStringBuilder 类,并实现了 Serializable 和 CharSequence 两个接口。
构造方法
有若干种构造方法,可以指定容量大小参数,如果没有指定则构造方法默认创建容量为16的字符串对象。如果 COMPACT_STRINGS 为 true,即使用紧凑布局则使用 LATIN1 编码(ISO-8859-1编码),则开辟长度为16的 byte 数组。而如果是 UTF16 编码则开辟长度为32的 byte 数组。
public StringBuilder() {
super(16);
}
AbstractStringBuilder(int capacity) {
if (COMPACT_STRINGS) {
value = new byte[capacity];
coder = LATIN1;
} else {
value = StringUTF16.newBytesFor(capacity);
coder = UTF16;
}
}
public StringBuilder(int capacity) {
super(capacity);
}
如果构造函数传入的参数为 String 类型,则会开辟长度为str.length() + 16的 byte 数组,并通过append方法将字符串对象添加到 byte 数组中。
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
类似地,传入参数为 CharSequence 类型时也做相同处理。
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
主要方法
append方法
如果传入 String 类型参数则调用父类的append方法将字符串对象添加到 StringBuilder 的 byte 数组中,然后返回 this。append 的逻辑为:
* String 对象为 null的话则在 StringBuilder 的 byte 数组中添加n u l l四个字符。
* 通过ensureCapacityInternal方法确保有足够的空间,如果没有则需要重新开辟空间。
* 通过putStringAt方法将字符串对象里面的 byte 数组复制到 StringBuilder 的 byte 数组中,使用了System.arraycopy进行复制。
* count 为已使用的字符数,将其加上复制的字符串长度。
* 返回 this。
public StringBuilder append(String str) {
super.append(str);
return this;
}
public AbstractStringBuilder append(String str) {
if (str == null) {
return appendNull();
}
int len = str.length();
ensureCapacityInternal(count + len);
putStringAt(count, str);
count += len;
return this;
}
首先获取现有的容量大小。
* 如果需要的容量大于现有容量,则需要扩充容量,并且将原来的数组复制过来。
* newCapacity
方法用于确定新容量大小,将现有容量大小扩大一倍再加上2,如果还是不够大则直接等于需要的容量大小。
delete方法
该方法用于将指定范围的字符删掉,逻辑为:
* end 不能大于已使用字符数 count,大于的话则令其等于 count。
* 通过checkRangeSIOOBE检查范围合法性。
* 通过shift方法实现删除操作,其通过System.arraycopy来实现,即把 end 后面的字符串复制到 start 位置,即相当于将中间的字符删掉。
* 修改已使用字符数 count 值。
* 返回 this。
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
public AbstractStringBuilder delete(int start, int end) {
int count = this.count;
if (end > count) {
end = count;
}
checkRangeSIOOBE(start, end, count);
int len = end - start;
if (len > 0) {
shift(end, -len);
this.count = count - len;
}
return this;
}
private void shift(int offset, int n) {
System.arraycopy(value, offset << coder,
value, (offset + n) << coder, (count - offset) << coder);
}
总结:stringbuilder 效率高,线程不安全,长度可变,初始长度16,当调用有参构造方法时长度为参数长度+16,当调用append方法时会先判断需要容量是否大于现有容量,如果大于则扩容一倍+2,如果还大于,则直接等于需要容量。
更多详细内容见https://blog.csdn.net/wangyangzhizhou/article/details/80446222