String/StringBuilder/StringBuffer
String
JAVA中有字符串公共池,如果兩個字符串具有相同的內容,它們將共享公共池內同一存儲器。這樣做是爲了節省對經常使用的字符串存儲。另一方面,通過new操作符和構造器創建的String對象,都存儲在堆中,即是兩個String的內容相同,它們也是相互獨立的,沒有共用存儲。用equal()方法比較兩個字符串的內容,用==比較兩個變量的引用。
String中使用字符數組(char[ ])來保存字符串:
/** The value is used for character storage. */
private final char value[];
由源碼可知char之前有final修飾,String對象是不可變的。
StringBuilder
StringBuilder繼承了AbstractStringBuilder類。也是使用char數組保存字符串
/**
* The value is used for character storage.
*/
char[] value;
但是它的對象是可變的,當StringBuilder對象進行append操作時,會調用父類的append方法。其中再調用ensureCapacityInternal(int)方法,確保value的容量能滿足append後的長度,ensureCapacityInternal(int)方法中,若append後的長度大於當前value的length,則調用expandCapacity(int)方法進行擴容。expandCapacity(int)方法擴容規模爲當前長度*2+2。使用Array.copyOf()方法,指定需要複製的數組和新的數組長度,返回一個新的字符數組對象。然後回到append()方法中,把要添加的字符串複製到擴容後的value中。源碼如下:
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return appendNull();
int len = sb.length();
ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);
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;
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);
}
StringBuffer
StringBuffer與StringBuilder都繼承了同一個父類AbstractStringBuilder。與StringBuilder不同的是,StringBuffer對方法或調用的方法加了同步鎖(synchronized),因此StringBuffer是線程安全的。而StringBuilder是線程不安全的。
使用場景
1、如果操作少量的數據,使用String
2、單線程操作字符串緩衝區且有大量數據,使用StringBuilder。
3、多線程操作字符串緩衝區且有大量數據,使用StringBuffer。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.