Stringbuffer與Stringbuilder原始碼學習和對比

範大腳腳發表於2017-11-22

String/StringBuffer/StringBuilder的異同

(1)相同點

觀察原始碼會發現,三個類都是被final修飾的,是不可被繼承的。
(2)不同點

String的物件是不可變的;而StringBuilder和StringBuffer是可變的

檢視原始碼可以發現,StringBuffer的實現都新增了Synchronized同步,因此StringBuffer是執行緒安全的,而StringBuilder不是執行緒安全的

String中的offset,value,count都是被final修飾的不可修改的;而StringBuffer和StringBuilder中的value,count都是繼承自AbstractStringBuilder類的,沒有被final修飾,說明他們在執行期間是可修改的,而且沒有offset變數。


StringBuffer/StringBuilder原始碼學習

String底層是一個char陣列:

1
private final char value[];

同樣,StringBuffer/StringBuilder都繼承了AbstractStringBuilder,

底層的實現也是通過一個char型陣列:

1
char[] value;

它們的預設構造方法都是初始化一個長度為16的字元陣列,

1
2
3
4
5
6
7
public StringBuilder() {
       super(16);
   }
    
 public StringBuilder() {
       super(16);
   }

或者使用傳入的容量進行初始化:

1
2
3
4
5
6
7
public StringBuilder(int capacity) {
        super(capacity);
    }
     
  public StringBuffer(int capacity) {
        super(capacity);
    }

再具體的實現就不去看了,有用到再研究。

使用舉例

貼一個以前學習Java的例子,

String s1 = “hello”; 

s1=“world”; 

這個操作其實是:其實是建立了兩個String物件。

String s2 = “hello” 

s2 += “world”; 

這操作是:先建立一個String物件,在接下來進行字串連線的時候,有建立了一個StringBuilder(jdk1.5前是StringBuffer),然後呼叫append()方法,最後呼叫toString()方法。 

有此可以看出String對字元的操作比直接使用Stringbuffer(或者StringBuild)要多出附加的操作,而且String是不可變物件,使用String對字串操作會產生大量的、多餘java物件。所以結果是:影響效能,佔用空間。 

舉例: 

分別使用String和StringBuffer對字串“0123456789”累加10000次,然後統計耗時多長:

1
2
3
4
5
6
7
8
9
10
String str = "0123456789";
    String str2 = "";
   int count = 10000;
    long start = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
       str2 += str;
    }
    long end = System.currentTimeMillis();
    long time = (end - start);
    System.out.println(time);

  

執行多次,在我的機器上平均時間約等於3300,即3.3秒,下面用StringBuffer來操作,檢視結果

1
2
3
4
5
6
7
8
9
10
11
String str = "0123456789";
StringBuffer sb = new StringBuffer();
int count = 10000;
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
sb.append(str);
}
String str2 = sb.toString();
long end = System.currentTimeMillis();
long time = (end - start);
System.out.println(time);

  

同樣在我的機器上結果平均結果小於10,即0.01秒,兩者相差300多倍,而且隨著迴圈次數的增加這個差距逐漸增大 。

 


本文轉自邴越部落格園部落格,原文連結:http://www.cnblogs.com/binyue/p/3383008.html,如需轉載請自行聯絡原作者


相關文章