Java——StringBuffer 和 StringBuilder 類
一. StringBuffer 和 StringBuilder
當對字串進行修改的時候,需要使用 StringBuffer 和 StringBuilder 類。
和 String 類不同的是,StringBuffer 和 StringBuilder 類的物件能夠被多次的修改,並且不產生新的未使用物件。
StringBuilder 類和 StringBuffer 之間的最大不同在於 StringBuilder 的方法不是執行緒安全的(不能同步訪問)。
由於 StringBuilder 相較於 StringBuffer 有速度優勢,所以多數情況下建議使用 StringBuilder 類。然而在應用程式要求執行緒安全的情況下,則必須使用 StringBuffer 類。
public class Test{
public static void main( String args[]) {
StringBuffer sBuffer = new StringBuffer("Hello ");
sBuffer.append("World");
System.out.println(sBuffer);
}
}
二. StringBuffer 、Stringbuilder 方法
序號 | 方法描述 |
---|---|
1 | public StringBuffer append(String s) 將指定的字串追加到此字元序列。 |
2 | public StringBuffer reverse() 將此字元序列用其反轉形式取代。 |
3 | public delete(int start, int end) 移除此序列的子字串中的字元。 |
4 | public insert(int offset, int i) 將 int 引數的字串表示形式插入此序列中。 |
5 | replace(int start, int end, String str) 使用給定 String 中的字元替換此序列的子字串中的字元。 |
package demo;
public class Test{
public static void main( String args[]) {
StringBuffer sBuffer = new StringBuffer("Hello ");
sBuffer.append("World");
int [] arr= {1,2,3};
sBuffer.append(arr[0]);
System.out.println(sBuffer); // Hello World1
sBuffer.append('A');
System.out.println(sBuffer); // Hello World1A
sBuffer.delete(11,15);
System.out.println(sBuffer); // Hello World
sBuffer.reverse();
System.out.println(sBuffer); // dlroW olleH
sBuffer.reverse();
System.out.println(sBuffer); // Hello World
StringBuilder sBuilder = new StringBuilder("Hello World");
System.out.println(sBuilder); // Hello World
sBuilder.insert(2, 'e');
System.out.println(sBuilder); // Heello World
sBuilder.insert(0,"hello ");
System.out.println(sBuilder); // hello Heello World
sBuilder.replace(0,6,"");
System.out.println(sBuilder); // Heello World
sBuilder.replace(1,2,"");
System.out.println(sBuilder); // Hello World
}
}
下面的列表裡的方法和 String 類的方法類似:
序號 | 方法描述 |
---|---|
1 | int capacity() 返回當前容量。 |
2 | char charAt(int index) 返回此序列中指定索引處的 char 值。 |
3 | void ensureCapacity(int minimumCapacity) 確保容量至少等於指定的最小值。 |
4 | void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 將字元從此序列複製到目標字元陣列 dst 。 |
5 | int indexOf(String str) 返回第一次出現的指定子字串在該字串中的索引。 |
6 | int indexOf(String str, int fromIndex) 從指定的索引處開始,返回第一次出現的指定子字串在該字串中的索引。 |
7 | int lastIndexOf(String str) 返回最右邊出現的指定子字串在此字串中的索引。 |
8 | int lastIndexOf(String str, int fromIndex) 返回 String 物件中子字串最後出現的位置。 |
9 | int length() 返回長度(字元數)。 |
10 | void setCharAt(int index, char ch) 將給定索引處的字元設定為 ch 。 |
11 | void setLength(int newLength) 設定字元序列的長度。 |
12 | CharSequence subSequence(int start, int end) 返回一個新的字元序列,該字元序列是此序列的子序列。 |
13 | String substring(int start) 返回一個新的 String ,它包含此字元序列當前所包含的字元子序列。 |
14 | String substring(int start, int end) 返回一個新的 String ,它包含此序列當前所包含的字元子序列。 |
15 | String toString() 返回此序列中資料的字串表示形式。 |
三. String,StringBuilder,StringBuffer三者的區別
(參考與:https://www.cnblogs.com/su-feng/p/6659064.html)
String,StringBuilder,StringBuffer 之間的區別主要是在兩個方面,即執行速度和執行緒安全這兩方面。
1. 執行速度快慢為:StringBuilder > StringBuffer > String
String最慢的原因:
String為字串常量,而 StringBuilder 和 StringBuffer 均為字串變數,即 String 物件一旦建立之後該物件是不可更改的,但後兩者的物件是變數,是可以更改的。
public class Test{
public static void main( String args[]) {
String str = "abc";
System.out.println(str); // abc
str += "de";
System.out.println(str); // abcde
}
}
如果執行這段程式碼會發現先輸出 “abc”,然後又輸出 “abcde”,好像是 str 這個物件被更改了,其實,這只是一種假象罷了,JVM 對於這幾行程式碼是這樣處理的,首先建立一個 String 物件 str,並把 “abc” 賦值給 str,然後在第三行中,其實JVM又建立了一個新的物件也名為 str,然後再把原來的 str 的值和 “de” 加起來再賦值給新的 str,而原來的 str 就會被 JVM 的垃圾回收機制(GC)給回收掉了,所以,str實際上並沒有被更改,也就是前面說的String物件一旦建立之後就不可更改了。所以,Java中對String物件進行的操作實際上是一個不斷建立新的物件並且將舊的物件回收的一個過程,所以執行速度很慢。
而StringBuilder和StringBuffer的物件是變數,對變數進行操作就是直接對該物件進行更改,而不進行建立和回收的操作,所以速度要比String快很多。
另外,有時候我們會這樣對字串進行賦值
public class Test{
public static void main( String args[]) {
String str = "abc" + "de";
System.out.println(str); // abcde
StringBuilder stringBuilder = new StringBuilder().append("abc").append("de");
System.out.println(stringBuilder); // abcde
}
}
這樣輸出結果也是“abcde”和“abcde”,但是 String 的速度卻比 StringBuilder 的反應速度要快很多,這是因為第1行中的操作和
String str="abcde";
是完全一樣的,所以會很快,而如果寫成下面這種形式
String str1 = "abc";
String str2 = "de";
String str = str1 + str2;
那麼JVM就會像上面說的那樣,不斷的建立、回收物件來進行這個操作了。速度就會很慢。
2. 執行緒安全
線上程安全上,StringBuilder 是執行緒不安全的,而 StringBuffer 是執行緒安全的
如果一個StringBuffer物件在字串緩衝區被多個執行緒使用時,StringBuffer中很多方法可以帶有synchronized關鍵字,所以可以保證執行緒是安全的,但StringBuilder的方法則沒有該關鍵字,所以不能保證執行緒安全,有可能會出現一些錯誤的操作。所以如果要進行的操作是多執行緒的,那麼就要使用StringBuffer,但是在單執行緒的情況下,還是建議使用速度比較快的StringBuilder。
3. 總結一下
String:適用於少量的字串操作的情況
StringBuilder:適用於單執行緒下在字元緩衝區進行大量操作的情況
StringBuffer:適用多執行緒下在字元緩衝區進行大量操作的情況