StringBuffer 源碼分析
阿新 • • 發佈:2017-08-21
進行 元素 return ring class max arr 源碼 pen
StringBuffer繼承了AbstractStringBuilder,我們主要來看下AbstractStringBuilder這個類:
AbstractStringBuilder
1)、成員
/**
* The value is used for character storage.
*/
char value[];
/**
* The count is the number of characters used.
*/
int count;
2)、方法
1、提供了兩種構造器
AbstractStringBuilder() {
}
AbstractStringBuilder( int capacity) {
value = new char[capacity];
}
可以看出,第二種構造器可以在構造對象的時候就指定維護的數組的初始大小
2、擴容
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}
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);
}
可以看出,如果維護的數組的長度不夠,則會將長度變為原來的兩倍
3、
public void trimToSize() {
if (count < value.length) {
value = Arrays.copyOf(value, count);
}
}
減少數組的長度到元素的個數
4、
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
if (newLength > value.length)
expandCapacity(newLength);
if (count < newLength) {
for (; count < newLength; count++)
value[count] = ‘\0‘;
} else {
count = newLength;
}
}
設置sequence長度
5、append方法
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);
str.getChars(0, len, value, count);
count = newCount;
return this;
}
//本方法是StringBuffer append方法的核心,主要就是在擴容後,將append的字符串直接拷貝到擴容後的數組的相關位置上,並沒有new其他不需要的對象
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > count) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, offset + srcBegin, dst, dstBegin,
srcEnd - srcBegin);
}
這裏與String拼接字符串的方式做一下比較:
String在進行“+”拼接時,會new臨時的StringBuffer對象,即 new StringBuilder().append(str).append("asjdkla").toString(),一旦在循環中做拼接字符串的操作,那麽將會new大量StringBuffer和String(StringBuffer的toString方法會new String),導致開銷極大
下面我們再看下String的concat方法
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
很明顯,這種方式比使用“+”的方式好一些,但是還是new了多余的String對象,一旦在循環中調用,還是對性能有很大影響的
StringBuffer 源碼分析