StringBuilder&StringBuffer
本文源码基于JDK8
StringBuilder与StringBuffer是两个常用的操作字符串的类。StringBuilder是线程不安全的,而StringBuffer是线程安全的;StringBuilder、StringBuffer都继承自AbstractStringBuilder
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value; //字符数组
int count;
}
- Serializable:可以序列化的标志;
- CharSequence接口:包含了charAt()、length() 、subSequence()、toString()这几个方法,String类也实现了这个接口;
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{}
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{}
append方法比较
AbstractStringBuilder抽象类的append方法
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);//确保不会溢出,必要是扩容
str.getChars(0, len, value, count);//将整个str拷贝到value的末尾
count += len; //增加计数
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) //如果会溢出,则扩容
expandCapacity(minimumCapacity);
}
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2; //新的容量是原容量的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);
}
注意:如果str是null,则会调用appendNull()方法。这个方法其实是追加了'n'、'u'、'l'、'l'这几个字符
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
StringBuffer
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
toStringCache这个变量是用于最近一次toString()方法的缓存,任何时候只要StringBuffer被修改了这个变量会被赋值为null;
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
总结
-
StringBuilder和StringBuffer都是可变字符串,前者线程不安全,后者线程安全。
-
StringBuilder和StringBuffer的大部分方法均调用父类AbstractStringBuilder的实现。其扩容机制首先是把容量变为原来容量的2倍加2。最大容量是Integer.MAX_VALUE,也就是0x7fffffff。
-
StringBuilder和StringBuffer的默认容量都是16,最好预先估计好字符串的大小避免扩容带来的时间消耗
public StringBuilder() {
super(16);
}
public StringBuffer() {
super(16);
}
- StringBuilder是jdk1.5引进的,而StringBuffer在1.0就有了;
网友评论