最近看Java性能优化的书,其中讲到字符串拼接推荐使用StringBuffer的append方法,而不是String的+。我测试过了,当拼接5万条数据的时候,相差非常大,请问一下,为什么有这么大的差别。底层是如何优化的?public class AppendStringTest {
  public static void main(String[] args){
  final int N=50000;
  String str="";
  long startTime=System.currentTimeMillis();
  for(int i=0;i<N;i++){
 str=str+"a"; 
  }
  long endTime=System.currentTimeMillis();
  
  System.out.println("Using String add+:"+(endTime-startTime));
  
  StringBuffer sb=new StringBuffer("abc");
  startTime=System.currentTimeMillis();
  for(int i=0;i<N;i++){
 sb.append("a");
  }
      String str2=sb.toString();
  endTime=System.currentTimeMillis();

  System.out.println("Using StringBuffer append:"+(endTime-startTime));
  }
}

解决方案 »

  1.   

    其实,如果不是很old的编译器,会自动帮你把字符串+转为StringBuilder的append来操作的。问题是编译器只能帮你简单转换,也就是在循环里,每次new一个StringBuilder,然后操作字符串加法。
    与你直接只new一个StringBuilder,处理N次加法,当然效率要差一些第一种情况,java6 编译器编译后反编译的代码for(int i = 0; i < 50000; i++)
                str = (new StringBuilder(java.lang.String.valueOf(str))).append("a").toString();
      

  2.   

    当你new数量足够多的对象时,并变成垃圾时,涉及到垃圾回收,就会让你的程序运行速度变的很慢
      

  3.   


    正解,如果不是在循环中的话,可以大胆使用“+”连接String,这样编译器会把代码优化成StringBuilder(jdk1.5以后的编译器)\StringBuffer(jdk1.4以前的编译器),但在循环中编译器并没有进一步对代码进行优化,每个循环创建一个StringBuilder(jdk1.5以后的编译器)\StringBuffer(jdk1.4以前的编译器)