① String aa = "aa" + "bb" + "cc";
②  StringBuffer aa = new StringBuffer("aa" + "bb" + "cc");
③  StringBuffer aa = new StringBuffer();
    aa.append("aa");
    aa.append("bb");
    aa.append("cc");以上3个方案哪个效率高??为什么??

解决方案 »

  1.   

    呵呵,如果你这样写当然是①
    因为编译器已经直接自动计算好了,已经不是在运行的时候才进行+了StringBuffer比String好,主要是在一个循环中才会明显,如果直接就是一行过没有在循环体内就没有什么问题
      

  2.   

    3效率高
    首先我们要明白String+String在内存中的动作
    比如:
    String a = "a";
    String b = "b";
    String c = a + b;
    实际上a+b的时候并不会把a和b所占的内存回收掉,而是a,b,c都占用一定的内存
    而StringBuffer则不同.
    public class performance {
    long startTime;
    long startMem;
    long endTime;
    long endMem;
    long time;
    long mem;

    public void count() {
    time = endTime-startTime;
    mem = startMem - endMem;

    }

    public String toString() {
    return "测试内存使用和运行时间";
    }

    public void print() {
    System.out.println("Use memory: "+ mem); 
    System.out.println("Use Time: "+ time);
    } public void Start() {
    startTime = System.currentTimeMillis(); 
    startMem = Runtime.getRuntime().freeMemory(); 
    }

    public void End() {
    endMem = Runtime.getRuntime().freeMemory();
    endTime = System.currentTimeMillis(); 
    }
    }
    你可以写一个main方法测测
      

  3.   

    小数据量无所谓,大数据量时用StringBuffer,速度会快很多(不是一个数量级)
      

  4.   

    要是我在这3句话的外面套上循环500次呢??①for(int i=0; i<500; i++){
    String aa = "aa" + "bb" + "cc";
    }
    ②  
    for(int i=0; i<500; i++){
    StringBuffer aa = new StringBuffer("aa" + "bb" + "cc");

    ③ 
    { StringBuffer aa = new StringBuffer();
        aa.append("aa");
        aa.append("bb");
        aa.append("cc");
    }哪个快??
      

  5.   

    楼上的楼上讲反了,显然大数据量时StringBuffer 会快很多,因为String 在作变动时都要产生新的String ,相当于要把整个字符串拷贝一便,而StrigBuffer 则不用
      

  6.   

    大对象的时候必须要使用StringBuffer,不然你会付出代价的。
      

  7.   

    String  何 StringBuffer的区别:
    String 是不变类  即是 final类型。
    所以
    每次产生String 时  都会在内存内 产生一份拷贝。
    比如 
    String  a="aaa";
    String b="bb";
    String  c=a+b;
    那么内存中将有 三个对象 产生三个副本。
    而StringBuffer 则不同
    它将2个字符串连接
    而不会进行新的内存分配
      

  8.   

    楼上说的大部分都有道理,在此我要补充一点~~StringBuffer是可变类,处理字符串相加或者改变字符串时不会分配新的内存~~这点上它有优势~~String类是不可变类,处理字符串会新建一个对象(分配内存),但JAVA虚拟机对其进行了优化~~
    使String类可以共享内存:
       如 String a = "abc"; String b = "abc",此时,a和b共享内存(指向同一个内存地址)
    不信你可以用System.out.println(a==b)试一下~~所以,此时内存中只建了一个"abc"的字符串~
    这是String类的优势~~具体哪个效率高还真难说,不同的情况会有不同的结果~~
      

  9.   

    大数据量的字符串连接时,StringBuffer会有明显的效率提高
    小数据量的时候无所谓啦就
      

  10.   

    在一般情况下String与 stringBuffer二种写法效率是一样,因为String通过编译器自动优化后,自动转化为StringBuffer实现,且默认容量为10. 因此,只有在 设定StringBufer()中的初始容量>10之后,才比String更有效率.
    应用StringBuffer,关键在于根据处理数据大小,设定一个适当的初始容量.
      

  11.   

        照你这么写的话,我觉得差不多,数据量不大,它们之间的差异更应该体现在数据量大的情况下,一般小数据量也差不多!    在选择用String对象还是用StringBuffer对象来代表一个字符串时,如果该字符串不会变更,则总是使用String对象,这将提高性能.
        
        如果程序频繁的执行字符串连接操作.或其他的字符串修改操作.则使用StringBuffer类来实现.可以提高效率.
      

  12.   

    大家的说法全都错了,我已经测试过了,是1最快,2其次,3最慢
    public class Test {
        long startTime;
        long startMem;
        long endTime;
        long endMem;
        long time;
        long mem;    public static void main(String[] args) {
            Test a = new Test();
            a.Start();
            
            for (int i = 0; i < 500; i++) {
                //StringBuffer aa = new StringBuffer("aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc");
               // StringBuffer aa = new StringBuffer();
               // aa.append("aaaaaaaaaaaaaaaaa");
               // aa.append("bbbbbbbbbbbbbbbbbbbbbb");
               // aa.append("ccccccccccccccccccccc");            String aa = "aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc";
            }
            a.End();
            a.count();
            a.toString();
            a.print();
        }    public void count() {
            time = endTime - startTime;
            mem = startMem - endMem;    }    public String toString() {
            return "测试内存使用和运行时间";
        }    public void print() {
            System.out.println("Use memory: " + mem);
            System.out.println("Use Time: " + time);
        }    public void Start() {
            startTime = System.currentTimeMillis();
            startMem = Runtime.getRuntime().freeMemory();
            System.out.println("start memory: " + startMem);
            System.out.println("start Time: " + startTime);
        }    public void End() {
            endMem = Runtime.getRuntime().freeMemory();
            endTime = System.currentTimeMillis();
            System.out.println("end memory: " + endMem);
            System.out.println("end Time: " + endTime);
        }
    大家谁不信可以试试
      

  13.   

    原因是什么呢??因为是每次循环都做了初始化,而不是在一个字符串上座修改
    第一个建立了4个String对象,但是aa内存分配是一次完成的
    第2个建立了3个String对象,一个StringBuffer,StringBuffer的建立是初始化的String+16,所以内存占用量比1大,建立一个StringBuffer要比String慢,所以速度也不行
    第3个,建立了3个String对象,一个StringBuffer,StringBuffer的初始大小是16,如果第一个append的字符串>16要重新分配内存,一次,大小是第一个子符串的大小+16,已此类推,如果append的字符串比较大的话,第3个方案要分配3次内存,所以速度最慢
      

  14.   

    一个血的教训:
    曾经用sax解析一份大的xml文件的时候,把值放在String,用+连接。
    运行一段时间,程序总会等待好几分钟来回收垃圾,而且这个时候什么事情都干不了的。
    等待几分钟意味着时间是正常的100倍量级,甚至千倍。
      

  15.   

    1楼的已经说的很清楚了。
    大家都知道StringBuffer在连接字符方面效率高,但还要看是什么情况下用。
      

  16.   

    那是因为你的测试程序写得不正确造成的,
    StringBuffer sb = new StringBuffer();
    for(int i = 0; i < 10000; i++)
      sb.append("FFFFF");和 
    String a = "";
    for(int i = 0; i < 10000; i++)
      a += "FFFFF";
    你这样就可以发现其中的巨大差异
      

  17.   

    顶一下  ChDw(米)把变量定义放在循环体外是个很基础的优化常识喔!
      

  18.   

    ChDw(米)  首先感谢你的回答我当然知道什么样的情况下有巨大差异,我就使要问这样的特殊情况,只是想给大家提个醒,不要只记结果,不分析什么情况。你可以自己看看我的问题,再看看我的测试程序,你怎么可以说我写的不对呢??
      

  19.   

    我为什么说你的不正确,这是因为
            for (int i = 0; i < 500; i++) {
                String aa = "aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc";
            }
    这样做法,首先编译器自动帮助你优化成
            for (int i = 0; i < 500; i++) {
                String aa = "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccc";
            }所以在这个过程中,根本没有生成任何对象(那个是字符串常量,只会在类中存在一份,aa每次都指向这个常量罢了),所以没有任何拷贝动作
            for (int i = 0; i < 500; i++) {
                StringBuffer aa = new StringBuffer("aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc");        }优化成:
            for (int i = 0; i < 500; i++) {
                StringBuffer aa = new StringBuffer("aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccc");
            }
    即,除了一个常量以外,还会在循环中生成一个StringBuffer对象,但是它是在构造函数中已经完成了,没有后续函数调用!最后一种 :
           for (int i = 0; i < 500; i++) {
                StringBuffer aa = new StringBuffer();
                aa.append("aaaaaaaaaaaaaaaaa");
                aa.append("bbbbbbbbbbbbbbbbbbbbbb");
                aa.append("ccccccccccccccccccccc");
            }编译器无法优化(它没有这么聪明),所以这种方法会有三个字符串常量,并每次循环有构造函数外还额外调用多三次方法从上述可以看到,这个根本是因为编译器的优化造成的
    如果你将程序改成
    String constA = "aaaaaaaaaaaaaaaaa";
    String constB = "bbbbbbbbbbbbbbbbbbbbbb";
    String constC = "ccccccccccccccccccccc";
    再将后面相应的换成上面的constA, constB, constC,你就会发现这三者的速度是相当的
      

  20.   

    String constA = "aaaaaaaaaaaaaaaaa";
    String constB = "bbbbbbbbbbbbbbbbbbbbbb";
    String constC = "ccccccccccccccccccccc";
    long t1 = System.currentTimeMillis();
    for (int i = 0; i < 500000; i++) {
    1. //String aa = constA + constB + constC;2. //StringBuffer aa = new StringBuffer(constA + constB + constC);3. StringBuffer aa = new StringBuffer();
    aa.append(constA);
    aa.append(constB);
    aa.append(constC);4. StringBuffer aa = new StringBuffer(constA);
    aa.append(constB);
    aa.append(constC);}
    long t2 = System.currentTimeMillis();
    System.out.println("(T2-T1):" + (t2 - t1));
    在我的机器上面
    1. 用时 700ms
    2. 用时 1100ms
    3. 用时 620ms
    4. 用时 550ms
      

  21.   

    请问  ChDw(米) 学了多长时间的JAVA了啊
    没别的意思,只是感觉你分析的不错,我是新手,
      

  22.   

    请问编译器怎么优化下面的代码
    String a="afdsafda";
    String a=a+"fs";还有更有效率的方法做到这件事情么
      

  23.   

    String a = "afdsafda";
    String b = a + "fs";这样的代码,编译器无法优化
    但是这样可以:
    final String a = "afdsafda";
    final String b = a + "fs";
      

  24.   

    数据量大时用StringBuffer,很快的
      

  25.   

    ChDw(米)
    看了你的讲解是明白了不少。
    但是我还是不明白1和2比3多消耗的时间在那里呢??