• java常用的几种字符串拼接方法比较


    字符串的拼接,常使用到的大概有4种方式:

    1.直接使用"+"号

    2.使用String的concat方法

    3.使用StringBuilder的append方法

    4.使用StringBuffer的append方法


    由于String是final类型的,因此String对象都是属于不可变对象,因此,在需要对字符串进行修改操作的时候(比如字符串的连接或者是替换),String总是会生成新的对象。

    1.“+”

    如果不考虑其他,使用“+”号来连接字符串无疑是最方便、最快捷的方式。但是事实上,使用“+”号连接字符串的效率并不高,。

    贴出测试用的demo

    public class Str {
    
        public static void main(String[] args) {
            String str1 = "hello";
            String str2 = "wolrd";
    
            String str = str1 + str2;
            System.out.println(str);
        }
    
    }
    

    贴出Str通过编译之后产生的字节码文件

    public class com.fzkj.str.Str {
      public com.fzkj.str.Str();
        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 hello
           2: astore_1
           3: ldc           #3                  // String wolrd
           5: astore_2
           6: new           #4                  // class java/lang/StringBuilder
           9: dup
          10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
          13: aload_1
          14: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          17: aload_2
          18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          21: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          24: astore_3
          25: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
          28: aload_3
          29: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          32: return
    }
    

    通过上面的字节码文件可以看出,在执行String str = str1 + str2;这一条语句的时候,其实底层是调用了StringBuilder的append方法来实现,就是说使用“+”号连接字符串的时候,底层会new一个StringBuilder对象,调用该对象的append方法将字符串拼接起来,最后通过toString方法返回拼接之后的值。

    也就是字符串str1+str2就等效于下面的代码:

    String str1 = "hello";
    String str2 = "wolrd";
    StringBuilder sb = new StringBuilder();
    sb.append(str1).append(str2);
    String s = sb.toString();
    

    在数据量很大的时候,比如说循环一万次,那就会创建一万个StringBuilder对象。所以说使用"+"号拼接字符串的效率很低。

    最后在看一下使用"+"号拼接str1和str2,100000次的耗时。

    public class Str {
    
        public static void main(String[] args) {
            String str1 = "hello";
            String str2 = "wolrd";
    
            long startTime = System.currentTimeMillis();
            System.out.println("开始执行时间:"+ startTime);
            for (int i = 0; i < 100000; i++) {
                String str = str1 + str2;
            }
            long stopTime = System.currentTimeMillis();
            System.out.println("结束执行时间:"+ stopTime);
            System.out.println("执行100000次字符串拼接总共耗时:"+(stopTime - startTime)+"ms");
    
        }
    }
    
    开始执行时间:1591326544582
    结束执行时间:1591326544601
    执行100000次字符串拼接总共耗时:19ms
    
    2.concat

    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);
        }
    

    从concat方法的源码中可以看出来,concat就是申请了一个char数组,将需要拼接的字符串放到这个数组中,最后转换为String返回。

    还是记录拼接100000次,总共的耗时

    public class Str {
    
        public static void main(String[] args) {
            String str1 = "hello";
            String str2 = "wolrd";
            // 使用concat连接字符串
            String concat = str1.concat(str2);
            long startTime = System.currentTimeMillis();
            System.out.println("开始执行时间:"+ startTime);
            for (int i = 0; i < 100000; i++) {
                String str = str1.concat(str2);
            }
            long stopTime = System.currentTimeMillis();
            System.out.println("结束执行时间:"+ stopTime);
            System.out.println("执行100000次字符串拼接总共耗时:"+(stopTime - startTime)+"ms");
    
        }
    }
    
    开始执行时间:1591328017552
    结束执行时间:1591328017561
    执行100000次字符串拼接总共耗时:9ms
    
    3.StringBuffer/StringBuilder

    这两个类都继承了同一个抽象类AbstractStringBuilder;而这两个类的append方法都是调用的父类中的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;
        }
    

    而它俩的区别就是StringBuffer的append方法上加了synchronized关键字,因此是线程安全的。

    public class Str {
    
        public static void main(String[] args) {
            String str1 = "hello";
            String str2 = "wolrd";
            
            StringBuffer sb = new StringBuffer();
            long startTime = System.currentTimeMillis();
            System.out.println("开始执行时间:"+ startTime);
            for (int i = 0; i < 100000; i++) {
                sb.append(str1);
            }
            long stopTime = System.currentTimeMillis();
            System.out.println("结束执行时间:"+ stopTime);
            System.out.println("StringBuffer执行100000次字符串拼接总共耗时:"+(stopTime - startTime)+"ms");
    
            StringBuilder sb1 = new StringBuilder();
            long startTime1 = System.currentTimeMillis();
            System.out.println("开始执行时间:"+ startTime1);
            for (int i = 0; i < 100000; i++) {
                sb1.append(str1);
            }
            long stopTime1 = System.currentTimeMillis();
            System.out.println("结束执行时间:"+ stopTime1);
            System.out.println("StringBuilder执行100000次字符串拼接总共耗时:"+(stopTime1 - startTime1)+"ms");
        }
    }
    
    开始执行时间:1591328952926
    结束执行时间:1591328952933
    StringBuffer执行100000次字符串拼接总共耗时:7ms
    开始执行时间:1591328952934
    结束执行时间:1591328952936
    StringBuilder执行100000次字符串拼接总共耗时:2ms
    

    StringBuilder的性能比StringBuffer的性能要好点。
    从上面的结果中,可以得出一个结论,那就是这四种的效率由快到慢依次是:
    StringBudiler>StringBuffer>concat>+
    事实上,在拼接的字符串很少的情况下,concat的效率其实是比StringBuilder的效率还要高的。
    所以在实际的使用过程中,要根据自己的需求选择使用。。


    持续更新~~~

  • 相关阅读:
    WinForm中AssemblyInfo.cs文件参数具体讲解
    ISO18000-6B和ISO18000-6C(EPC C1G2)标准的区别
    Win8.1下VM与Hyper-v冲突解决方法
    Mifare l卡特性简介
    【Python爬虫】beautifulsoup4库的安装与调用
    【Python爬虫】已知jpg文件url-下载图片
    【Python爬虫】测试
    【Python爬虫】Requests库的安装
    【Python】以模块化做比赛模拟
    【真随笔】未来出路,在哪里?
  • 原文地址:https://www.cnblogs.com/yanghuanxi/p/16768921.html
Copyright © 2020-2023  润新知