1
2StringBuffer 是安全執行緒的
3StringBuilder 不保證安全執行緒(在1.5中引入的),一般情況下比StringBuffer快
4
5一個String對象的長度是固定的,不能改變它的內容,或者是附加新的字元至String對象中。您也許會使用+來串聯字串以達到附加新字元或字串的目的,但+會產生一個新的String執行個體。如果程式對這種附加字串的需求很頻繁,並不建議使用+來進行字串的串聯。在物件導向程式設計中,最好是能重複運用已產生的對象,對象的產生需要記憶體空間與時間,不斷地產生String執行個體是一個沒有效率的行為。
6J2SE 5.0提供java.lang.StringBuilder類,使用這個類所產生的對象預設會有16個字元的長度,您也可以自行指定初始長度。如果附加的字元超出可容納的長度,則StringBuilder對象會自動增加長度以容納被附加的字元。如果有頻繁作字串附加的需求,使用StringBuilder會讓程式的效率大大提高。通過下面的簡單測試程式就可以知道效能差距有多大。
7ü 範例6.5 AppendStringTest.java
8public class AppendStringTest {
9 public static void main(String[] args) {
10 String text = "";
11
12 long beginTime = System.currentTimeMillis();
13 for(int i = 0; i < 10000; i++)
14 text = text + i;
15 long endTime = System.currentTimeMillis();
16 System.out.println("執行時間:" + (endTime - beginTime));
17
18 StringBuilder builder = new StringBuilder("");
19 beginTime = System.currentTimeMillis();
20 for(int i = 0; i < 10000; i++)
21 builder.append(String.valueOf(i));
22 endTime = System.currentTimeMillis();
23 System.out.println("執行時間:" + (endTime - beginTime));
24 }
25}
26
27在範例6.5中首先使用+來串聯字串,使用System.currentTimeMillis()取得for迴圈執行前、後的系統時間,這樣就可以得知for迴圈執行了多久。以下是我的電腦上的測試資料:
28
29執行時間:4641
30執行時間:16
31可以看到執行的時間差距很大,這說明了使用+串聯字串所帶來的負擔。如果有經常作附加字串的需求,建議使用StringBuilder。事實上就範例6.5來說,第二個for迴圈執行時間還可以更短,因為append()也可以接受基礎資料型別 (Elementary Data Type),所以不必特地使用String.valueOf()方法從int取得String。改為以下的方式,執行時間可以大幅縮短:
32for(int i = 0; i < 10000; i++)
33 builder.append(i);
34使用StringBuilder最後若要輸出字串結果,可以用toString()方法。可以使用length()方法得知目前對象中的字元長度,而capacity()可返回該對象目前可容納的字元容量。另外,StringBuilder還有像insert()方法可以將字元插入指定的位置,如果該位置以後有字元,則將所有的字元往後移;deleteChar()方法可以刪除指定位置的字元,而reserve()方法可以反轉字串。詳細的使用可以查詢java.lang.StringBuilder的API檔案說明。
35StringBuilder是J2SE 5.0才新增的類,在J2SE 5.0之前的版本若有相同的需求,則使用java.lang.StringBuffer。事實上,StringBuilder被設計為與StringBuffer具有相同的操作介面。在單機非多線程(Multithread)的情況下使用StringBuilder會有較好的效率,因為StringBuilder沒有處理同步(Synchronized)問題。StringBuffer則會處理同步問題,如果StringBuilder會在多線程下被操作,則要改用StringBuffer,讓對象自行管理同步問題。
36