你必須搞清楚的String,StringBuilder,StringBuffer

String,StringBuilder 以及 StringBuffer 這三個類的關係與區別一直是 Java 的經典問題,此次就來說一下關於這三個類的一些知識數組

一. 簡單對比

  • String : 字符常量
  • StringBuilder : 字符變量
  • StringBuffer : 字符變量

String 屬於常量類型,被聲明爲 final class,全部的屬性也都是 final 類型,所以 String 對象一旦建立,便不可更改; StringBuilder / StringBuffer 兩個類屬於變量類型,是能夠更改的,它們都是爲了解決字符串因爲拼接產生太多中間對象的問題而提供的類。安全

  • 運行速度 StringBuilder > StringBuffer > Stringbash

  • 線程安全: StringBufferapp

  • 非線程安全 : StringBuilder函數

StringBuilder 在本質上和 StringBuffer 沒有太大區別,可是因爲 StringBuilder 去掉了 StringBuffer 擁有的線程安所有分,所以有效減小了開銷。所以,StringBuilder 是大部分狀況下字符串拼接操做的首選性能

二. String 處理字符串

例一:

String s = "abcd";
s = s + "fgh";
複製代碼

不少人做這樣的字符串處理的時候會誤認爲 String 類型是可變的。優化

但其實 JVM 處理這段代碼的過程是這樣的:首先建立 s 對象,賦值「abcd」 ,而後處理第二行代碼時,再建立一個 s 對象,賦值 「abcdfgh」,而後將第一個 s 對象垃圾回收。ui

因此至關於第一個 s 沒更改過,第二個 s 是新的對象spa

例二:

String str = 「This is only a」 + 「simple」 + 「test」;
複製代碼

這段代碼至關於 String str = 「This is only a simple test」;線程

例三:

String str2 = "This is only a";
String str3 = "simple";
String str4 = "test";
String str1 = str2 +str3 + str4;
複製代碼

這段代碼一樣會按照例一的過程來處理

三. StringBuilder / StringBuffer 構造特性

這兩個對象在構造的過程當中,首先按照默認大小申請一個字符數組(char[]), 默認容量爲 16 個字符,但若是超出,會使用 Arrays.copyOf() 成倍擴容 16,32,64, 128...,固然這樣會影響性能,所以能夠在建立對象時按照須要自定義其容量

源代碼:
//默認 16 個字符
public StringBuilder() {
    super(16);
}
//構造函數定義容量
public StringBuilder(int capacity) {
    super(capacity);
}
複製代碼

四. String 與 StringBuilder 處理字符串拼接對比

咱們都知道,進行字符串拼接操做時推薦使用 StringBuilder,可是是否是何時都推薦使用 StringBuilder 來代替 String 進行字符串拼接?顯然不是的。

例一:

String str = "123";
String str1 = str + "456";
String str2 = new StringBuilder().append(str).append("def").toString();
複製代碼

在這種狀況下,兩種處理方式效率差異不大

JDK1.5 以後, String 的字符串拼接操做會被編譯器自動轉換爲 StringBuilder 並調用 append 方法,最後調用 StringBuilder 的 toString 方法返回一個從新建立的字符串,因爲這樣的優化方案,使得兩個類在這種狀況下的處理效率差異不大;而在 Java 9 中,爲了更加統一字符串操做優化,提供了 StringConcatFactory,做爲一個統一的入口,更加優化了字符串拼接操做。

例二:

String str = "";
for (int i = 0; i < 1000; i++) {
    str += "12345";
}

StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    stringBuilder.append("12345");
}
複製代碼

這種狀況下,StringBuilder 更快

在循環中,每執行一次 「+」,都會建立一個 String 對象,所以會有大量對象建立和回收的消耗。

簡單來講,在循環中對同一個字符串對象作字符串拼接,優先選擇 StringBuilder

例三

String str1 = "123" + "456" + "789";

String str2 = new StringBuilder("123").append("456").append("789").toString();
複製代碼

這種狀況下,String 更快

咱們都知道 String str1 = "123" + "456" + "789"; 實際上是等同於 String str1 = "123456789";的,而 StringBuilder 反而須要屢次調用 append 方法。

相關文章
相關標籤/搜索