首先,由于String是final类,所以其一旦赋值是不可修改的,同时其自带方法,类似与substring,replace,等,都是对原String拷贝后的再修改,所以String的使用不是很方便,也会很费存储空间和效率。
所以,StringBuffer是一个具有对象引用传递特点的字符串对象。可以调用其方法动态的进行增加、插入、修改和删除操作,且不用像数组那样事先指定大小,从而实现多次插入字符,一次整体取出的效果,因而操作字符串非常灵活方便。
最后可以通过toString()方法再将操作的结果存入Stirng
StringBuilder是线程不安全的,而StringBuffer是线程安全的。StringBuilder是比较快的。
他们都是继承抽象类AbstractStringBuilder实现的。
char[] value;
int count;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
用一个char[]数组保存字符串,可以在构造的时候指定初始容量方法。
他们的扩容机制是一样的。
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > 0)
ensureCapacityInternal(minimumCapacity);
}
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;
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);
}
扩容是由expandCapacity()实现的,StringBuilder和StringBuffer的大部分方法均调用父类AbstractStringBuilder的实现。其扩容机制首先是把容量变为原来容量的2倍加2。最大容量是Integer.MAX_VALUE,也就是0x7fffffff。
StringBuilder和StringBuffer的默认容量都是16,最好预先估计好字符串的大小避免扩容带来的时间消耗。
StringBuffer为了实现同步,很多方法使用lSynchronized修饰
源码如下
public synchronized int length() {
return count;
}
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
两者用法是一样的
StringBuffer/StringBuilder