Java 基礎複習——StringBuffer 和 StringBuilder

2023-07-01 12:01:30

StringBuffer 和 StringBuilder

StringBuffer 類 簡介

  • java.lang.StringBuffer 代表可變的字元序列,可以對字串內容進行增刪

  • 很多方法和 String 相同,但 StringBuffer 是可變長度的

  • StringBuffer 是一個容器

注意:

  1. StringBuffer 的直接父類別是 AbstractStringBuilder 有屬性 char[] value,不是 final 修飾
  2. StringBuffer 實現了 Serializable,即 StringBuffer 的物件可以序列化(可以網路傳輸,可以儲存到檔案)
  3. StringBuffer 是一個 final 類,不能被繼承

StringBuffer 和 String 對比

  • String 儲存的是字串常數,裡面的值不能更改,每次 String 類的更新實際上就是更改地址,效率較低 // private final char[ ] value
  • StringBuffer 儲存的是字串變數,裡面的值可以更改,不用每次更新地址,效率較高 // char[ ] value 放在堆中

StringBuffer的構造器

// Constructor and Description
StringBuffer()
// 構造一個其中不帶字元的字串緩衝區,其初始容量為16個字元
StringBuffer(CharSequence seq)
// 構造一個字串緩衝區,包含與指定的CharSequener相同的字元
StringBuffer(int capacity)
// 構造一個其中不帶字元,但具有指定初始容量的的字串緩衝區,即對char[]大小進行指定
StringBuffer(String str)
//// 構造一個字串緩衝區,並將其內容初始化為指定的字串內容

StringBuffer 和 String 的相互轉換

String ---> StringBuffer

String s = "hello";

方式一:

 StringBuffer b1 = new StringBuffer(s);

方式二:

StringBuffer b2 = new StringBuffer();
b2.append(s);

StringBuffer ---> String

方式一:

String s2 = b1.toString()

方式二:

String s3 = new String(b1);

StringBuffer 常用方法

StringBuffer	append()	// 增
StringBuffer	delete(int start, int end)	// 刪
StringBuffer	insert() // 插入
StringBuffer	replace(int start, int end, String str)	// 改
int	indexOf(String str) // 查
int	length() // 獲取長度

練習題

String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str);  // 呼叫的AbstractStringBuilder的 appendNull方法
System.out.println(sb.length()); // 4 null --> value = {'n', 'u', 'l', 'l'}
System.out.println(sb.capacity()); // 16


System.out.println(sb);
StringBuffer sb1 = new StringBuffer(str); //NullPointerException super(str.length() + 16);
System.out.println(sb1);

StringBuilder 類 簡介

  • 一個可變的字元序列。此類提供與 StringBufffer 相容的API,但不保證同步。被設計作為 StringBuffer 的建議替換,用在字串被單個執行緒使用的時候。如果可能,建議有限採用該類,因在在大多數實現中,他比 StringBuffer 要快。兩者的方法基本相同

注意:

  1. StringBuilder 是 final 類,不能被繼承
  2. 繼承了 AbstractStringBuilder,屬性 Char[ ] value,因此字元序列是在堆中
  3. 實現了 Serialzable 介面,序列號(所謂序列號即可以儲存型別和資料本身)
  4. StringBuilder 的方法,沒有做互斥的處理,即沒有 synchronized 關鍵字,因此在單執行緒的情況下使用

String、StringBuffer 和 StringBuilder 的比較

  1. StringBuilder 和 StringBuffer 非常類似,均代表可變的字元序列,且方法也一樣

  2. String 不可變字元序列,效率低,但是複用率高

  3. StringBuffer:可變字元序列,效率較高(增刪)、執行緒安全

  4. StringBuilder:可變字元序列,效率最高,執行緒不安全

  5. String 使用注意說明:

    String s = "a"; // 建立一個字串
     s += "b";
    /*
    實際上原來的 "a" 字串物件已經丟棄了,現在又產生了一個字串是 s + "b" (即"ab")。如果多次執行這些改變串內容的操作,會導致的大量副本字串物件存在記憶體中,降低效率。如果這樣的操作放到迴圈中,會極大的影響程式的效能
    
    ==> 結論:如果我們對String做大量修改,不要使用String
    */
    

    效率測試

long startTime = 0L;
long endTime = 0L;
// StringBuffer
StringBuffer stringBuffer = new StringBuffer("");
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
    stringBuffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的執行時間:" + (endTime - startTime));

// StringBuilder
StringBuilder stringBuilder = new StringBuilder("");
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
    stringBuilder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的執行時間:" + (endTime - startTime));

//String
String text = "";
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
    text += i;
}
endTime = System.currentTimeMillis();
System.out.println("String的執行時間:" + (endTime - startTime));

// StringBuffer的執行時間:5
//StringBuilder的執行時間:2
//String的執行時間:1463
// 測試結果:StringBuilder > StringBuffer > String

String、StringBuffer 和 StringBuilder 的選擇

使用的原則、結論:

  1. 如果字串存在大量的修改操作,一般使用StringBuffer 和 StringBuilder

  2. 如果字串存在大量的修改操作,並在單執行緒的情況,使用StringBuilder

  3. 如果字串存在大量的修改操作,並在多執行緒的情況,使用StringBuffer

  4. 如果字串很少修改,被多個物件參照,使用 String,比如設定資訊等