Java編譯器對String
做了特殊處理,使得我們可以直接用+拼接字串。
考察下面 下麪的回圈程式碼:
String s = "";
for (int i = 0; i < 10; i++) {
s = s + "," + i;
}
雖然可以直接拼接字串,但是,在回圈中,每次回圈都會建立新的字串物件,然後扔掉舊的字串。這樣,絕大部分字串都是臨時物件,不但浪費記憶體,還會影響GC效率。
爲了能高效拼接字串,Java標準庫提供了StringBuilder
,它是一個可變物件,可以預分配緩衝區,這樣,往StringBuilder
中新增字元時,不會建立新的臨時物件:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append(',');
sb.append(i);
}
String s = sb.toString();
StringBuilder
還可以進行鏈式操作:
public class test {
public static void main(String srga[]){
StringBuilder sb = new StringBuilder();
sb.append("Mr ")
.append("Bob")
.append("!")
.insert(0, "Hello, ");
System.out.println(sb.toString());
}
}
如果我們檢視StringBuilder
的原始碼,可以發現,進行鏈式操作的關鍵是,定義的append()
方法會返回this,這樣,就可以不斷呼叫自身的其他方法。
仿照StringBuilder
,我們也可以設計支援鏈式操作的類。例如,一個可以不斷增加的計數器:
// 鏈式操作
public class Main {
public static void main(String[] args) {
Adder adder = new Adder();
adder.add(3)
.add(5)
.inc()
.add(10);
System.out.println(adder.value());
}
}
class Adder {
private int sum = 0;
public Adder add(int n) {
sum += n;
return this;
}
public Adder inc() {
sum ++;
return this;
}
public int value() {
return sum;
}
}
注意:對於普通的字串+操作,並不需要我們將其改寫爲StringBuilder,因爲Java編譯器在編譯時就自動把多個連續的+操作編碼爲StringConcatFactory的操作。在執行期,StringConcatFactory會自動把字串連線操作優化爲陣列複製或者StringBuilder操作。
你可能還聽說過StringBuffer,這是Java早期的一個StringBuilder的執行緒安全版本,它通過同步來保證多個執行緒操作StringBuffer也是安全的,但是同步會帶來執行速度的下降。
StringBuilder和StringBuffer介面完全相同,現在完全沒有必要使用StringBuffer。
StringBuilder
是可變物件,用來高效拼接字串;
StringBuilder
可以支援鏈式操作,實現鏈式操作的關鍵是返回範例本身;
StringBuffer
是StringBuilder的執行緒安全版本,現在很少使用。