资讯专栏INFORMATION COLUMN

“+=”和append的区别

ztyzz / 1543人阅读

摘要:和的区别是面试中出现频率较高的一个题目了,下面我们就来分析一下这两者的区别吧。所以我们在平时写代码的时候一定注意,不要再循环中使用操作,效率很低的。

“+=”和append的区别是面试中出现频率较高的一个题目了,下面我们就来分析一下这两者的区别吧。
首先看一下这段代码的结果:

String s1 = "a";
String s2 = s1 + "b";
System.out.println(s2 == "ab"); // false

输出结果是false;

javap将其反编译之后的结果如下:

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String a
       2: astore_1
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."":()V
      10: aload_1
      11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      14: ldc           #6                  // String b
      16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      22: astore_2
      23: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
      26: aload_2
      27: ldc           #9                  // String ab
      29: if_acmpne     36
      32: iconst_1
      33: goto          37
      36: iconst_0
      37: invokevirtual #10                 // Method java/io/PrintStream.println:(Z)V
      40: return

根据结果我们可以看到:

虚拟机开始是定义了一个字符串”a“将其入栈;

然后new了一个StringBuilder对象,将”a“封装到Sb对象中;

之后用StringBuilder的append()方法来完成"a"和"b"的拼接;

所以这里的"ab"字符串本质上是一个StringBuilder对象,所以再去跟常量"ab"去比较的话会是false;
这样看来用"+"和append效率似乎是一样的,并没有像网上说的那样”+“操作比append()更消耗性能。

那下面我们来看一下这两者在循环中是什么结果:
首先是”+=“操作:

public static void main(String[] args) {
    String[] arr = new String[]{"a","b","c"};
    String result = "";
    for (int i = 0 ; i < arr.length; i ++) {
        result += arr[i];
    }
    System.out.println(result);
}

反编译结果如下:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_3
       1: anewarray     #2                  // class java/lang/String
       4: dup
       5: iconst_0
       6: ldc           #3                  // String a
       8: aastore
       9: dup
      10: iconst_1
      11: ldc           #4                  // String b
      13: aastore
      14: dup
      15: iconst_2
      16: ldc           #5                  // String c
      18: aastore
      19: astore_1
      20: ldc           #6                  // String
      22: astore_2
      23: iconst_0
      24: istore_3
      25: iload_3
      26: aload_1
      27: arraylength
      28: if_icmpge     58
                                                                                                                                                                            43,1          34%
      31: new           #7                  // class java/lang/StringBuilder
      34: dup
      35: invokespecial #8                  // Method java/lang/StringBuilder."":()V
      38: aload_2
      39: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      42: aload_1
      43: iload_3
      44: aaload
      45: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      48: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      51: astore_2
      52: iinc          3, 1
      55: goto          25
      58: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
      61: aload_2
      62: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      65: return

可以看到从25: iload_355: goto 25两句构成了一个循环,而31: new #7 // class java/lang/StringBuilder创建StringBuilder对象语句在循环内,所以会创建多个
SB对象;

下面我们把代码改为append()实现:

    public static void main(String[] args) {
        String[] arr = new String[]{"a","b","c"};
        StringBuilder result = new StringBuilder();
        for (int i = 0 ; i < arr.length; i ++) {
            result.append(arr[i]);
        }
        System.out.println(result);
    }

反编译后:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_3
       1: anewarray     #2                  // class java/lang/String
       4: dup
       5: iconst_0
                                                                                                                                                                            85,7          68%
       6: ldc           #3                  // String a
       8: aastore
       9: dup
      10: iconst_1
      11: ldc           #4                  // String b
      13: aastore
      14: dup
      15: iconst_2
      16: ldc           #5                  // String c
      18: aastore
      19: astore_1
      20: new           #6                  // class java/lang/StringBuilder
      23: dup
      24: invokespecial #7                  // Method java/lang/StringBuilder."":()V
      27: astore_2
      28: iconst_0
      29: istore_3
      30: iload_3
      31: aload_1
      32: arraylength
      33: if_icmpge     50
      36: aload_2
      37: aload_1
      38: iload_3
      39: aaload
      40: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      43: pop
      44: iinc          3, 1
      47: goto          30
      50: getstatic     #9                  // Field java/lang/System.out:Ljava/io/PrintStream;
      53: aload_2
      54: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      57: return

可以发现在由30: iload_347: goto 30构成的循环体内没有new操作,而是放到了循环外部
20: new #6 // class java/lang/StringBuilder

由此得出,在循环时使用+=会创建多个StringBuilder对象,而使用append(),只会创建一个。
所以我们在平时写代码的时候一定注意,不要再循环中使用+=操作,效率很低的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73363.html

相关文章

  • jQuery DOM节点创建、插入、删除

    摘要:通过方法添加的元素刚好相反,内容在方法前面,无论是一个选择器表达式或创建作为标记上的标记它都将被插入到目标容器的末尾。主要的不同是语法特别是插入内容和目标的位置。 DOM节点的创建 DOM创建节点及节点属性 首先,介绍如何使用JavaScript创建div节点元素,主要包括创建div节点元素的属性和创建div节点元素的样式两大部分内容 创建流程: 创建节点(常见的:元素、属性和文本)...

    rainyang 评论0 收藏0
  • java学习(六) —— java中StringStringBuffer区别

    摘要:中有三个类可以对字符进行操作是进行单个字符操作的类。类中的方法偏重于对字符串的变化,例如追加插入和删除等,这个也是和类的主要区别。类属于一种辅助类,可预先分配指定长度的内存块建立一个字符串缓冲区。 前言 String和StringBuffer都是java中关于字符操作的类 尤其String,经常看到类似这样的赋值代码 String str = Hello World,看起来就好像in...

    Paul_King 评论0 收藏0
  • String, StringBufferStringBuilder

    摘要:在中,是不可变类型,所以对于字符串的操作提供了两个辅助类和。考虑如下代码在利用直接进行拼接时,每次循环都会生成一个新的对象,也就是说等同这样运行的效率明显是低于显式调用的。 在Java中,String是不可变类型,所以对于字符串的操作提供了两个辅助类:StringBuffer和StringBuilder。 这个两个类的主要区别在于: StringBuilder的效率更高 Stri...

    cartoon 评论0 收藏0
  • python“=”与C++区别

    摘要:先来看中普通变量传值对于普通变量和是一样的,接下来看看的列表由此可以看到传值时,传递的是指针。由于中的元组相当与中的常量数组,不分析元组,接下来看看中的字典变量字典中传递的也是地址,接下来看看一种特殊的字典,即字典中对应的值是个 先来看python中普通变量传值 data1=1 data2=data1 data2+=1 print data2,data1 2 1 对于普通变量pytho...

    lewif 评论0 收藏0
  • 为什么不建议在for循环中使用"+"进行字符串拼接

    摘要:使用可以方便的对字符串进行拼接。该方法使用进行声明,说明是一个线程安全的方法。所以,阿里巴巴开发手册建议循环体内,字符串的连接方式,使用的方法进行扩展。但是,还要强调的是如果不是在循环体中进行字符串拼接的话,直接使用就好了。 摘要: 学习阿里巴巴Java开发手册。 原文:为什么阿里巴巴不建议在for循环中使用+进行字符串拼接 微信公众号:Hollis Fundebug经授权转载,...

    caoym 评论0 收藏0

发表评论

0条评论

ztyzz

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<