1. 程式人生 > >StringBuffer 源碼分析

StringBuffer 源碼分析

進行 元素 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); } 可以看出,如果維護的數組的長度不夠,則會將長度變為原來的兩倍 3public void trimToSize() { if (count < value.length) { value = Arrays.copyOf(value, count); } } 減少數組的長度到元素的個數
4public 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 源碼分析