StringBuilder的append方法和String+String的区别?

mybeta 2013-07-24 09:46:20

StringBuilder sb = new StirngBuilder();
sb.append("a").append("b").append("c").append("d");





String str = "";
str += "a";
str += "b";
str += "c";
str += "d";


在上面的例子中,“a”、“b”、“c”、“d”都应该会首先在常量池中分配空间吧,这样上面两端代码就应该差不多啊,但为什么是第一段代码效率更高呢?求解释
...全文
26501 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
水货大帝 2013-07-25
  • 打赏
  • 举报
回复
楼上回答挺详细的,差不多了。
引用 4 楼 jsjszg 的回复:
StringBuilder和StringBuffer,字符串是存放在char[]中的,char[]是存放在堆中的。 相比String每次+都重新创建一个String对象,重新开辟一段内存不同,StringBuilder和StringBuffer的append都是直接把String对象中的char[]的字符直接拷贝到StringBuilder和StringBuffer的char[]上,效率比String的+高得多。当然,当StringBuilder和StringBuffer的char[]长度不够时,也会重新开辟一段内存。 另外,StringBuffer是线程安全的,StringBuilder不是线程安全的。
lkq_david 2013-07-25
  • 打赏
  • 举报
回复
个人理解和1楼差不多,"ab"在"a"+"b"的时候是新建的
jsjszg 2013-07-24
  • 打赏
  • 举报
回复
不止,每次String变动,还会重现创建String对象,而创建新的对象时,有可能会触发GC
hippoppower 2013-07-24
  • 打赏
  • 举报
回复
引用 4 楼 jsjszg 的回复:
StringBuilder和StringBuffer,字符串是存放在char[]中的,char[]是存放在堆中的。 相比String每次+都重新创建一个String对象,重新开辟一段内存不同,StringBuilder和StringBuffer的append都是直接把String对象中的char[]的字符直接拷贝到StringBuilder和StringBuffer的char[]上,效率比String的+高得多。当然,当StringBuilder和StringBuffer的char[]长度不够时,也会重新开辟一段内存。 另外,StringBuffer是线程安全的,StringBuilder不是线程安全的。
也就是说 快得原因就是因为StringBuilder预先开辟了空间, append的时候只是向内存地址赋值; 而String总要不断的现开辟空间. 也因此String占的空间也会相对大一些! ?
jsjszg 2013-07-24
  • 打赏
  • 举报
回复 4
StringBuilder和StringBuffer,字符串是存放在char[]中的,char[]是存放在堆中的。 相比String每次+都重新创建一个String对象,重新开辟一段内存不同,StringBuilder和StringBuffer的append都是直接把String对象中的char[]的字符直接拷贝到StringBuilder和StringBuffer的char[]上,效率比String的+高得多。当然,当StringBuilder和StringBuffer的char[]长度不够时,也会重新开辟一段内存。 另外,StringBuffer是线程安全的,StringBuilder不是线程安全的。
lcf 2013-07-24
  • 打赏
  • 举报
回复
“a”是占了,"ab"没占啊,所以"ab"在"a"+"b"的时候是新建的,而sb.append("a").append('b")则没有
mybeta 2013-07-24
  • 打赏
  • 举报
回复
引用 1 楼 lcf 的回复:
str += "a"; 你要分解来看: str = str + "a"; 而str + "a" 会创建一个新的String对象,就慢了。你要知道String对象一旦创建就是不能被改变的,要达到字符串拼接的效果,就得不停创建新对象。 StringBuilder直到最后sb.toString()才会创建String对象,之前都没有创建新对象(在你的例子中是的,但是如果你append的总长度超过一定范围——默认是16——就会创建一个新的数组,来装下更多的String)
JAVA中创建的String是不是都是放常量池中啊?比如sb.append("a")中的“a”是不是在常量池中占了空间的啊?
lcf 2013-07-24
  • 打赏
  • 举报
回复
str += "a"; 你要分解来看: str = str + "a"; 而str + "a" 会创建一个新的String对象,就慢了。你要知道String对象一旦创建就是不能被改变的,要达到字符串拼接的效果,就得不停创建新对象。 StringBuilder直到最后sb.toString()才会创建String对象,之前都没有创建新对象(在你的例子中是的,但是如果你append的总长度超过一定范围——默认是16——就会创建一个新的数组,来装下更多的String)
huntor 2013-07-24
  • 打赏
  • 举报
回复 4
javac会把 str += "b"; 变成一个StringBuilder的append 操作。 相当于一个 new StringBuilder().append("a").append("b").toString(). 比自己调用append费事多了。
        StringBuilder builder = new StringBuilder("a");
        String s = builder.append("b").append("c").append("d").toString();

        String a = "a";
        a += "b";
        a += "c";
        a += "d";
javap -c 的输出:
    Code:
       0: new           #2                  // class java/lang/StringBuilder
       3: dup
       4: ldc           #3                  // String a
       6: invokespecial #4                  // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
       9: astore_1
      10: aload_1
      11: ldc           #5                  // String b
      13: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      16: ldc           #7                  // String c
      18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      21: ldc           #8                  // String d
      23: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      26: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      29: astore_2
      30: ldc           #3                  // String a
      32: astore_3
      33: new           #2                  // class java/lang/StringBuilder
      36: dup
      37: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
      40: aload_3
      41: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      44: ldc           #5                  // String b
      46: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      49: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      52: astore_3
      53: new           #2                  // class java/lang/StringBuilder
      56: dup
      57: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
      60: aload_3
      61: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      64: ldc           #7                  // String c
      66: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      69: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      72: astore_3
      73: new           #2                  // class java/lang/StringBuilder
      76: dup
      77: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
      80: aload_3
      81: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      84: ldc           #8                  // String d
      86: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      89: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      92: astore_3
      93: return

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧