精华内容
下载资源
问答
  • java字符串拼接

    万次阅读 2017-11-02 17:33:53
    这篇文章主要介绍了Java字符串拼接的一些细节分析,本文着重剖析了字符串拼接的一些性能问题、技巧等内容,需要的朋友可以参考下 工作日忙于项目的逻辑实现,周六有点时间,从书柜里拿出厚厚的英文版Thinking ...
    
    
    这篇文章主要介绍了Java中字符串拼接的一些细节分析,本文着重剖析了字符串拼接的一些性能问题、技巧等内容,需要的朋友可以参考下

    工作日忙于项目的逻辑实现,周六有点时间,从书柜里拿出厚厚的英文版Thinking In Java,读到了字符串对象的拼接。参考着这本书做个翻译,加上自己思考的东西,写上这篇文章记录一下。

    不可变的String对象

    在Java中,String对象是不可变的(Immutable)。在代码中,可以创建多个某一个String对象的别名。但是这些别名都是的引用是相同的。
    比如s1和s2都是”droidyue.com”对象的别名,别名保存着到真实对象的引用。所以s1 = s2

    复制代码代码如下:

    String s1 = "droidyue.com";
    String s2 = s1;
    System.out.println("s1 and s2 has the same reference =" + (s1 == s2));

    Java中仅有的重载运算符

    在Java中,唯一被重载的运算符就是字符串的拼接相关的。+,+=。除此之外,Java设计者不允许重载其他的运算符。

    拼接剖析

    真的有性能代价么

    了解了上面两点,可能会有这样的思考,既然Sting对象不可变,那么多个(三个及以上)字符串拼接必然产生多余的中间String对象。

    复制代码代码如下:

    String userName = "Andy";
    String age = "24";
    String job = "Developer";
    String info = userName + age + job;

    要得到上面的info,就会userName和age拼接生成临时一个String对象t1,内容为Andy24,然后有t1和job拼接生成最终我们需要的info对象,这其中,产生了一个中间的t1,而且t1创建之后,没有主动回收,势必会占一定的空间。如果是一个很多(假设上百个,多见于对对象的toString的调用)字符串的拼接,那么代价就更大了,性能一下会降低很多。

    编译器的优化处理

    真的会有上面的性能代价么,字符串拼接这么常用,没有特殊的处理优化么,答案是有的,这个优化进行在编译器编译.java到bytecode时。

    一个Java程序如果想运行起来,需要经过两个时期,编译时和运行时。在编译时,Java 编译器(Compiler)将java文件转换成字节码。在运行时,Java虚拟机(JVM)运行编译时生成的字节码。通过这样两个时期,Java做到了所谓的一处编译,处处运行。

    我们实验一下编译期都做了哪些优化,我们制造一段可能会出现性能代价的代码。

    复制代码代码如下:

    public class Concatenation {
      public static void main(String[] args) {
          String userName = "Andy";
          String age = "24";
          String job = "Developer";
          String info = userName + age + job;
          System.out.println(info);
      }
    }

    对Concatenation.java进行编译一下。得到Concatenation.class

    复制代码代码如下:

    javac Concatenation.java

    然后我们使用javap反编译一下编译出来的Concatenation.class文件。javap -c Concatenation。如果没有找到javap命令,请考虑将javap所在目录加入环境变量或者使用javap的完整路径。

    复制代码代码如下:

    17:22:04-androidyue~/workspace_adt/strings/src$ javap -c Concatenation
    Compiled from "Concatenation.java"
    public class Concatenation {
      public Concatenation();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return       

      public static void main(java.lang.String[]);
        Code:
           0: ldc           #2                  // String Andy
           2: astore_1
           3: ldc           #3                  // String 24
           5: astore_2
           6: ldc           #4                  // String Developer
           8: astore_3
           9: new           #5                  // class java/lang/StringBuilder
          12: dup
          13: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
          16: aload_1
          17: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          20: aload_2
          21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          24: aload_3
          25: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          28: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          31: astore        4
          33: getstatic     #9                  // Field java/lang/System.out:Ljava/io/PrintStream;
          36: aload         4
          38: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          41: return
    }

    其中,ldc,astore等为java字节码的指令,类似汇编指令。后面的注释使用了Java相关的内容进行了说明。 我们可以看到上面有很多StringBuilder,但是我们在Java代码里并没有显示地调用,这就是Java编译器做的优化,当Java编译器遇到字符串拼接的时候,会创建一个StringBuilder对象,后面的拼接,实际上是调用StringBuilder对象的append方法。这样就不会有我们上面担心的问题了。

    仅靠编译器优化?

    既然编译器帮我们做了优化,是不是仅仅依靠编译器的优化就够了呢,当然不是。 
    下面我们看一段未优化性能较低的代码

    复制代码代码如下:

    public void  implicitUseStringBuilder(String[] values) {
      String result = "";
      for (int i = 0 ; i < values.length; i ++) {
          result += values[i];
      }
      System.out.println(result);
    }

    使用javac编译,使用javap查看

    复制代码代码如下:

    public void implicitUseStringBuilder(java.lang.String[]);
        Code:
           0: ldc           #11                 // String 
           2: astore_2
           3: iconst_0
           4: istore_3
           5: iload_3
           6: aload_1
           7: arraylength
           8: if_icmpge     38
          11: new           #5                  // class java/lang/StringBuilder
          14: dup
          15: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
          18: aload_2
          19: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          22: aload_1
          23: iload_3
          24: aaload
          25: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          28: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          31: astore_2
          32: iinc          3, 1
          35: goto          5
          38: getstatic     #9                  // Field java/lang/System.out:Ljava/io/PrintStream;
          41: aload_2
          42: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          45: return

    其中8: if_icmpge 38 和35: goto 5构成了一个循环。8: if_icmpge 38的意思是如果JVM操作数栈的整数对比大于等于(i < values.length的相反结果)成立,则跳到第38行(System.out)。35: goto 5则表示直接跳到第5行。

    但是这里面有一个很重要的就是StringBuilder对象创建发生在循环之间,也就是意味着有多少次循环会创建多少个StringBuilder对象,这样明显不好。赤裸裸地低水平代码啊。

    稍微优化一下,瞬间提升逼格。

    复制代码代码如下:

    public void explicitUseStringBuider(String[] values) {
      StringBuilder result = new StringBuilder();
      for (int i = 0; i < values.length; i ++) {
          result.append(values[i]);
      }
    }

    对应的编译后的信息

    复制代码代码如下:

    public void explicitUseStringBuider(java.lang.String[]);
        Code:
           0: new           #5                  // class java/lang/StringBuilder
           3: dup
           4: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
           7: astore_2
           8: iconst_0
           9: istore_3
          10: iload_3
          11: aload_1
          12: arraylength
          13: if_icmpge     30
          16: aload_2
          17: aload_1
          18: iload_3
          19: aaload
          20: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          23: pop
          24: iinc          3, 1
          27: goto          10
          30: return

    从上面可以看出,13: if_icmpge 30和27: goto 10构成了一个loop循环,而0: new #5位于循环之外,所以不会多次创建StringBuilder.

    总的来说,我们在循环体中需要尽量避免隐式或者显式创建StringBuilder. 所以那些了解代码如何编译,内部如何执行的人,写的代码档次都比较高。

    以上文章,如有错误,请批评指正 。

       文章出处:http://www.jb51.net/article/59934.htm
    展开全文
  • 羞,Java 字符串拼接竟然有这么多姿势

    万次阅读 多人点赞 2019-11-14 05:57:55
    二哥,我今年大二,看你分享的《阿里巴巴 Java 开发手册》上有一段内容说:“循环体内,拼接字符串最好使用 StringBuilder 的 append 方法,而不是 + 号操作符。”到底为什么啊,我平常一直就用的‘+’号操作符啊!...

    二哥,我今年大二,看你分享的《阿里巴巴 Java 开发手册》上有一段内容说:“循环体内,拼接字符串最好使用 StringBuilder 的 append 方法,而不是 + 号操作符。”到底为什么啊,我平常一直就用的‘+’号操作符啊!二哥有空的时候能否写一篇文章分析一下呢?

    就在昨天,一位叫小菜的读者微信我说了上面这段话。

    我当时看到这条微信的第一感觉是:小菜你也太菜了吧,这都不知道为啥啊!我估计正在读这篇文章的你也会有同样的感觉。

    但扪心自问,在做程序员的前两年内,我也不知道为啥。遇到字符串拼接就上“+”号操作符,甭管是不是在循环体内。和小菜比起来,我当时可没他这么幸运,还有一位热心的“二哥”能够分享这份价值连城的开发手册。

    既然我这么热心分享,不如好人做到底,对不对?我就认认真真地写一篇文章,给小菜解惑一下。

    01、“+”号操作符

    要说姿势,“+”号操作符必须是字符串拼接最常用的一种了,没有之一。

    String chenmo = "沉默";
    String wanger = "王二";
    
    System.out.println(chenmo + wanger);
    

    我们把这段代码使用 JAD 反编译一下。

    String chenmo = "\u6C89\u9ED8"; // 沉默
    String wanger = "\u738B\u4E8C"; // 王二
    System.out.println((new StringBuilder(String.valueOf(chenmo))).append(wanger).toString());
    

    我去,原来编译的时候把“+”号操作符替换成了 StringBuilder 的 append 方法。也就是说,“+”号操作符在拼接字符串的时候只是一种形式主义,让开发者使用起来比较简便,代码看起来比较简洁,读起来比较顺畅。算是 Java 的一种语法糖吧。

    02、StringBuilder

    除去“+”号操作符,StringBuilder 的 append 方法就是第二个常用的字符串拼接姿势了。

    先来看一下 StringBuilder 类的 append 方法的源码:

    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    

    这 3 行代码没啥可看的,可看的是父类 AbstractStringBuilder 的 append 方法:

    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
    

    1)判断拼接的字符串是不是 null,如果是,当做字符串“null”来处理。appendNull 方法的源码如下:

    private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);
        final char[] value = this.value;
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }
    

    2)拼接后的字符数组长度是否超过当前值,如果超过,进行扩容并复制。ensureCapacityInternal 方法的源码如下:

    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
    

    3)将拼接的字符串 str 复制到目标数组 value 中。

    str.getChars(0, len, value, count)
    

    03、StringBuffer

    先有 StringBuffer 后有 StringBuilder,两者就像是孪生双胞胎,该有的都有,只不过大哥 StringBuffer 因为多呼吸两口新鲜空气,所以是线程安全的。

    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    

    StringBuffer 类的 append 方法比 StringBuilder 多了一个关键字 synchronized,可暂时忽略 toStringCache = null

    synchronized 是 Java 中的一个非常容易脸熟的关键字,是一种同步锁。它修饰的方法被称为同步方法,是线程安全的。

    04、String 类的 concat 方法

    单就姿势上来看,String 类的 concat 方法就好像 StringBuilder 类的 append。

    String chenmo = "沉默";
    String wanger = "王二";
    
    System.out.println(chenmo.concat(wanger));
    

    文章写到这的时候,我突然产生了一个奇妙的想法。假如有这样两行代码:

    chenmo += wanger
    chenmo = chenmo.concat(wanger)
    

    它们之间究竟有多大的差别呢?

    之前我们已经了解到,chenmo += wanger 实际上相当于 (new StringBuilder(String.valueOf(chenmo))).append(wanger).toString()

    要探究“+”号操作符和 concat 之间的差别,实际上要看 append 方法和 concat 方法之间的差别。

    append 方法的源码之前分析过了。我们就来看一下 concat 方法的源码吧。

    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
    

    1)如果拼接的字符串的长度为 0,那么返回拼接前的字符串。

    if (otherLen == 0) {
        return this;
    }
    

    2)将原字符串的字符数组 value 复制到变量 buf 数组中。

    char buf[] = Arrays.copyOf(value, len + otherLen);
    

    3)把拼接的字符串 str 复制到字符数组 buf 中,并返回新的字符串对象。

    str.getChars(buf, len);
    return new String(buf, true);
    

    通过源码分析我们大致可以得出以下结论:

    1)如果拼接的字符串是 null,concat 时候就会抛出 NullPointerException,“+”号操作符会当做是“null”字符串来处理。

    2)如果拼接的字符串是一个空字符串(""),那么 concat 的效率要更高一点。毕竟不需要 new StringBuilder 对象。

    3)如果拼接的字符串非常多,concat 的效率就会下降,因为创建的字符串对象越多,开销就越大。

    注意了!!!

    弱弱地问一下啊,还有在用 JSP 的同学吗?EL 表达式中是不允许使用“+”操作符来拼接字符串的,这时候就只能用 concat 了。

    ${chenmo.concat('-').concat(wanger)}
    

    05、String 类的 join 方法

    JDK 1.8 提供了一种新的字符串拼接姿势:String 类增加了一个静态方法 join。

    String chenmo = "沉默";
    String wanger = "王二";
    String cmower = String.join("", chenmo, wanger);
    System.out.println(cmower);
    

    第一个参数为字符串连接符,比如说:

    String message = String.join("-", "王二", "太特么", "有趣了");
    

    输出结果为:王二-太特么-有趣了

    我们来看一下 join 方法的源码:

    public static String join(CharSequence delimiter, CharSequence... elements) {
        Objects.requireNonNull(delimiter);
        Objects.requireNonNull(elements);
        // Number of elements not likely worth Arrays.stream overhead.
        StringJoiner joiner = new StringJoiner(delimiter);
        for (CharSequence cs: elements) {
            joiner.add(cs);
        }
        return joiner.toString();
    }
    

    发现了一个新类 StringJoiner,类名看起来很 6,读起来也很顺口。StringJoiner 是 java.util 包中的一个类,用于构造一个由分隔符重新连接的字符序列。限于篇幅,本文就不再做过多介绍了,感兴趣的同学可以去了解一下。

    06、StringUtils.join

    实战项目当中,我们处理字符串的时候,经常会用到这个类——org.apache.commons.lang3.StringUtils,该类的 join 方法是字符串拼接的一种新姿势。

    String chenmo = "沉默";
    String wanger = "王二";
    
    StringUtils.join(chenmo, wanger);
    

    该方法更善于拼接数组中的字符串,并且不用担心 NullPointerException。

    StringUtils.join(null)            = null
    StringUtils.join([])              = ""
    StringUtils.join([null])          = ""
    StringUtils.join(["a", "b", "c"]) = "abc"
    StringUtils.join([null, "", "a"]) = "a"
    

    通过查看源码我们可以发现,其内部使用的仍然是 StringBuilder。

    public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
        if (array == null) {
            return null;
        }
        if (separator == null) {
            separator = EMPTY;
        }
    
        final StringBuilder buf = new StringBuilder(noOfItems * 16);
    
        for (int i = startIndex; i < endIndex; i++) {
            if (i > startIndex) {
                buf.append(separator);
            }
            if (array[i] != null) {
                buf.append(array[i]);
            }
        }
        return buf.toString();
    }
    

    大家读到这,不约而同会有这样一种感觉:我靠(音要拖长),没想到啊没想到,字符串拼接足足有 6 种姿势啊,晚上回到家一定要一一尝试下。

    07、给小菜一个答复

    我相信,小菜读到我这篇文章的时候,他一定会明白为什么阿里巴巴不建议在 for 循环中使用”+”号操作符进行字符串拼接了。

    来看两段代码。

    第一段,for 循环中使用”+”号操作符。

    String result = "";
    for (int i = 0; i < 100000; i++) {
        result += "六六六";
    }
    

    第二段,for 循环中使用 append。

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 100000; i++) {
        sb.append("六六六");
    }
    

    这两段代码分别会耗时多长时间呢?在我的 iMac 上测试出的结果是:

    1)第一段代码执行完的时间为 6212 毫秒

    2)第二段代码执行完的时间为 1 毫秒

    差距也太特么大了吧!为什么呢?

    我相信有不少同学已经有了自己的答案:第一段的 for 循环中创建了大量的 StringBuilder 对象,而第二段代码至始至终只有一个 StringBuilder 对象。

    08、最后

    谢谢大家的阅读,原创不易,喜欢就随手点个赞👍,这将是我最强的写作动力。如果觉得文章对你有点帮助,还挺有趣,就关注一下我的公众号「沉默王二」;回复「666」更有 500G 高质量教学视频相送(已分门别类)。

    展开全文
  • Java字符串拼接原理

    千次阅读 2020-05-25 17:12:15
    字面量的拼接结果(注意:如果字符串拼接中有变量则结果不会进入字符串常量池) 调用String的intern方法可以将String存入字符串常量池 2. 字面量的拼接原理 java源码 package com.hgy; import java.util.Arrays;...

    JVM-字符串拼接原理

    1.那些字符串会进入字符串常量池

    1. 直接写的字面量
    2. 字面量的拼接结果(注意:如果字符串拼接中有变量则结果不会进入字符串常量池)
    3. 调用String的intern方法可以将String存入字符串常量池

    2. 字面量的拼接原理

    • java源码

      package com.hgy;
      
      import java.util.Arrays;
      import java.util.List;
      
      public class hello {
      
      	public static void main(String[] args) {
      		String a = "hello" + " world";
      	}
      }
      
      
    • 在idea中查看编译后的class文件

      //
      // Source code recreated from a .class file by IntelliJ IDEA
      // (powered by Fernflower decompiler)
      //
      
      package com.hgy;
      
      public class hello {
          public hello() {
          }
      
          public static void main(String[] args) {
              String a = "hello world";
          }
      }
      
      
    • 结论:

      • 以上面两个文件我们可以看出,这种字符串的拼接在编译期间就已经优化了,直接就合并为一个字符串;并且这个字符串存放在字符串常量池

    3. 字符串和变量拼接原理

    • java源码

      package com.hgy;
      
      import java.util.Arrays;
      import java.util.List;
      
      public class hello {
      
      	public static void main(String[] args) {
      		String v = "java";
      		String a = v + "hello" + " world";
      	}
      }
      
    • 利用jclasslib查看main方法的字节码命令

      • 如果一下名词不明白请阅读java虚拟机栈
      • 我们可以发现就简单的两行代码,产生了这么多的字节码命令;在代码中我简单解释了每一行的作用,
       0 ldc #2 <java>   // 从字符串常量池加载java
       2 astore_1  	   // 存储常量到索引为1的局部变量表中
       3 new #3 <java/lang/StringBuilder>  //给StringBuilder对象分配内存空间
       6 dup
       7 invokespecial #4 <java/lang/StringBuilder.<init>> //执行StringBuilder的构造方法
      10 aload_1   //获取局部变量表索引为1的引用地址,
      11 invokevirtual #5 <java/lang/StringBuilder.append> //把上面加载的内容作为参数传递给append方法
      14 ldc #6 <hello world> // 从字符串常量池加载hello world
      16 invokevirtual #5 <java/lang/StringBuilder.append> //把上面加载的内容作为参数传递给append方法
      19 invokevirtual #7 <java/lang/StringBuilder.toString> //调用toString方法
      22 astore_2 //结果存储到局部变量表
      23 return
      
    • 以上内容我们可以知道字符串拼接实际上就是创建了一个StringBuilder对象然后向里面append内容,最后调用toString方法获得结果

    3.1 为什么结果没有存储在常量池

    • 从上述字节码指令已经知道了字符串拼接结果是StringBuilder的toString方法的结果,那么toString里面具体做了什么事情,又是为什么结果不在常量池?

    • 一下是StringBuilder.toString的源码以及字节码指令

          @Override
          public String toString() {
              // Create a copy, don't share the array
              //此处value为一个char数组【我的jdk版本为jdk8】
              return new String(value, 0, count);
          }
      
      
       0 new #80 <java/lang/String>
       3 dup
       4 aload_0
       5 getfield #234 <java/lang/StringBuilder.value>
       8 iconst_0
       9 aload_0
      10 getfield #233 <java/lang/StringBuilder.count>
      13 invokespecial #291 <java/lang/String.<init>>
      16 areturn
      
    • 以上代码可以很好的解释实际上最终是调用了String的构造方法传入一个char数组,那么最终的结果肯定也就在咱么的堆空间

    展开全文
  • Java字符串拼接之String、StringBuffer和StringBuilder的性能 作者:谢景,撰写:2019-4-16 在c#中,字符串拼接是利用+号运算符重载实现的,但是在Java中虽然+号运算符也能实现字符串拼接,但是性能差。 下面介绍...

    Java字符串拼接之String、StringBuffer和StringBuilder的性能

    作者:谢景,撰写:2019-4-16

    在c#中,字符串拼接是利用+号运算符重载实现的,但是在Java中虽然+号运算符也能实现字符串拼接,但是性能差。
    下面介绍一下关于字符的相关的类。

    • String 类对象不可变,一旦修改 String的值就是隐形的重建了一个新的对象,释 放了原 String对象
    例如:String str=str+"a";
    相当于  先声明一个新的String:String str1=new String(str+"a");
           然后再将新的String赋值给旧的str:str=str1;
    
    • StringBuffer和StringBuilder类是可以通过append()、insert()、reverse()…等方法 来修改值。创建的对象是可变
    • StringBuffer:线程安全的; StringBuilder:线程非安全的
    • 字符串连接 String 的 + 比 StringBuffer(StringBuilder) 的 Append() 性能差了很多
    • 三者在执行速度方面的比较:StringBuilder > StringBuffer > String

    下面通过代码实践来验证一下上面的结论:

    public static void ddd(){	
    	//-----------------String-----------------------
    	String string=new String("");
    	Date date=new Date();//循环前声明一个实例化当前时间
    	for (int i = 0; i < 10000; i++) {
    		string+="1";
    	}
    	Date date1=new Date();//循环后声明再一个实例化当前时间
    	//获取后面的时间减去前面的时间的值
    	System.out.println("String: "+(date1.getTime()-date.getTime()));
    	//-----------------StringBuffer-----------------------
    	StringBuffer buffer=new StringBuffer("");
    	Date date2=new Date();//循环前声明一个实例化当前时间
    	for (int i = 0; i < 10000; i++) {
    		buffer.append("1");//StringBuffer、StringBuilder不能用+号运算符拼接字符
    	}
    	Date date3=new Date();//循环后声明再一个实例化当前时间
    	//获取后面的时间减去前面的时间的值
    	System.out.println("StringBuffer: "+(date3.getTime()-date2.getTime()));
    }
    

    结果如下图:
    在这里插入图片描述
    上图证明StringBuffer 比String拼接字符执行速度快很多,
    又因为 StringBuffer:线程安全的; StringBuilder:线程非安全的
    线程安全是已消耗速率为代价的,由此可以证明:
    三者在执行速度方面的比较:StringBuilder > StringBuffer > String

    展开全文
  • java字符串拼接,自动填充指定内容。
  • Java字符串拼接效率和String,StringBuilder,StringBuffer三者的区别 拼接字符串,用String, StringBuffer,StringBuilder。StringBuilder是jdk1.5中新增的。 测试类如下: public class TestStringConcat { ...
  • Java 字符串拼接效率比较

    万次阅读 多人点赞 2016-04-26 23:33:13
    字符串拼接的三种方法 ① 加号 ② concat方法 ③ StringBuilder(或StringBuffer)的append方法2 程序例子package
  • Java中提供了三种字符串拼接的方法:+、concat()以及append()方法。
  • 字符串拼接一般使用“+”,但是“+”不能满足大批量数据的处理,Java中有以下五种方法处理字符串拼接,各有优缺点,程序开发应选择合适的方法实现。 1. 加号 “+” 2. String contact() 方法 3. StringUtils....
  • 老生常谈之Java字符串拼接

    万次阅读 2015-12-10 14:44:38
    本文讲解Java语言中常见的几种字符串拼接方式的特点及其使用情形
  • 字符串拼接是我们在Java代码中比较经常要做的事情,就是把多个字符串拼接到一起。 我们都知道,String 是 Java 中一个不可变的类,所以他一旦被实例化就无法被修改。 不可变类的实例一旦创建,其成员变量的值就不...
  • java字符串拼接小结

    千次阅读 2017-03-10 08:15:52
    早期的版本中,字符串拼接是会在常量区创建对象的,比如如下代码 String str1 = "tom"; String str2 = "cat"; String str5 = str1 + str2;第三行是会在常量区创建一个String对象tomcat的,所以不少编程规范都会...
  • Java字符串拼接与拆分

    2019-09-22 21:43:41
    当左右两个量其中有一个为String类型时,用plus方式可将两个量转成字符串拼接。 String a=""; int b=0xb; String c=a+b; 2. concat方式 当两个量都为String类型且值不为null时,可以用concat方式。 String a="a...
  • C\C++\Java字符串拼接比较

    千次阅读 2013-04-13 15:18:32
    C\C++\Java字符串拼接比较: 昨天买好小米盒子,自己折腾了一会然后就教会老妈怎么玩,怎么看还珠格格之后,我闲来无事,突然想起了上次一个项目处理字符串遇到的性能问题,然后就仔细考虑了一下,越考虑发现需要注意的...
  • java 字符串拼接为什么不能用null

    千次阅读 2018-10-24 14:57:26
    然后去拼接字符串,在查询的时候报错,debug检查出来,最终的参数字符串str里面居然有null,如图:   所以拼接字符串不能用null,原因如下: s = s+"word"; 等价于 s = String.valueOf(s)+"...
  • java字符串拼接真的很简单吗?

    千次阅读 2018-07-28 15:54:51
    进行字符串直接拼接的功能,如以下示例: String provice = "Jiang Su"; String city = "Nan Jing"; String address = provice + city;  那么代码第三句,究竟做了什么呢?我们利用vim编写...
  • java字符串拼接引号转义

    千次阅读 2017-10-12 11:06:22
    "\""+areas+"\"";

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 125,002
精华内容 50,000
关键字:

java字符串拼接

java 订阅