public String statement1(){
String s ="";
for(int i=0; i < numItems(); i++){
s += lineForItem(i);
}
return s;
}
public String statement2(){
StringBuffer s = new StringBuffer(numItems()*LINE_WIDTH);
for(int i=0; i < numItems(); i++){
s.append(lineForItem(i));
}
return s.toString();
}
String s ="";
for(int i=0; i < numItems(); i++){
s += lineForItem(i);
}
return s;
}
public String statement2(){
StringBuffer s = new StringBuffer(numItems()*LINE_WIDTH);
for(int i=0; i < numItems(); i++){
s.append(lineForItem(i));
}
return s.toString();
}
方法2的效率要比方法1的效率高。
原則很簡單: 不要使用 字符串鏈接操作符來合并多個字符串,除非性能無關緊要。相反,應該使用StringBuffer的append方法,或者采用其它的方案,比如使用字符數組,或者每次只處理一個字符串,而不是將它們組合起來。
Tip1 初始化 StringBuffer 時,可以使用帶長度參數的構造函數盡量使用帶長度參數的構造函數。這樣預先計算了總長度,消除了內存重分配。
Tip2 JDK 的自動優化
public static String concat4(String s1, String s2, String s3, String s4, String s5, String s6) {
return s1 + s2 + s3 + s4 + s5 + s6;
}
return s1 + s2 + s3 + s4 + s5 + s6;
}
上面這段代碼執行的時候,Java會自動使用StringBuilder.append()函數來進行連接。所以這時,使用字符串連接符反而很快,甚至比使用 StringBuffer 還快。
Tip 3 需要線程安全的地方使用 StringBuffer,不需要線程安全的地方使用 StringBuilder 。 String類是不可變類,任何對String的改變都會引發新的String對象的生成;而StringBuffer則是可變類,任何對它所指代的字符串的改變都不會產生新的對象。當改變字符串內容時,采用StringBuffer能獲得更好的性能。既然是為了獲得更好的性能,那么采用 StringBuffer能夠獲得最好的性能嗎?答案是NO!為什么?如果你讀過《Think in Java》,而且對里面描述HashTable和HashMap區別的那部分章節比較熟悉的話,你一定也明白了原因所在。對,就是支持線程同步保證線程安全而導致性能下降的問題。HashTable是線程安全的,很多方法都是synchronized方法,而HashMap不是線程安全的,但其在單線程程序中的性能比HashTable要高。StringBuffer和StringBuilder類的區別也在于此,新引入的StringBuilder類不是線程安全的,但其在單線程中的性能比StringBuffer高。