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的效率還要高的。
所以在實際的使用過程中,要根據自己的需求選擇使用。。


持續更新~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM