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