你還在循環里面用+號拼接字符串嗎?
前言
對于初學Java的人來說,在學習String的時候,肯定有無數個人和我們講過,”盡量不要使用+拼接字符串,效率不好,應該使用append “,但真相真的是這樣的嗎?下面我們來通過實際代碼來測試一下+號與append的效率問題。
代碼分析
public class Demo {
public static void main(String[] args){
String str = "";
long start = System.currentTimeMillis();
for(int i=0; i<100000; i++)
str += "a";
long end = System.currentTimeMillis();
System.out.println(end - start);
StringBuilder sb = new StringBuilder();
start = System.currentTimeMillis();
for(int i=0; i<100000; i++)
sb.append("a");
str = sb.toString();
end = System.currentTimeMillis();
System.out.println(end - start);
}
}
我們分別在循環中分別用+好和append來循環拼接字符串。分別打印出他們的時間:
編譯,運行結果如下:
我們可以發現效率確實差距非常的明顯。別急,下面我們繼續來通過javap命令來查看他的字節碼文件指令:
我們可以發現使用+號拼接字符串,在循環體立面每次都會new一個StringBuilder對象,然后調用append方法來追加字符串。
下面我們看一下使用append拼接的字節碼指令:
綜上我們可以發現,在循環體里面我們使用+號拼接字符串的時候,編譯器每次都會給我們創建一個Stringbuilder對象,這也正是再循環體里面使用+號性能差的根本原因。難道這就可以說明我們永遠都不要使用+號來拼接字符串了嘛?其實這是不完全正確的。下面我們再來一組測試:
測試代碼:
public class Test {
public static void main(String[] args){
String a = "a";
String b = "a";
String c = "a";
String d = "a";
String e = a + b + c;
e += d;
}
}
我們可以通過javap命令來查看以上字節碼文件的指令如下:我們會發現只幫助我們new了2個StringBuilder對象。我們可以得到如下結論:對于此處的str = str + “a”,編譯器會處理為new StringBuilder().append(str).append(“a”),不管一次性+幾個字符串,只要+拼接全部在一條語句中,就只會new一次,循環中+拼接被斷成了十萬條語句,那自然就會new十萬次。
總結
我們在循環體中不要使用+號來拼接字符串,使用append來代替,但是不在循環體里面使用+號完全不會影響性能,甚至編譯器還做了優化。對于此處的str = str + “a”,編譯器會處理為new StringBuilder().append(str).append(“a”),不管一次性+幾個字符串,只要+拼接全部在一條語句中,就只會new一次,循環中+拼接被斷成了十萬條語句,那自然就會new十萬次。小伙伴們,你們GET了新技能沒?