1. 程式人生 > 實用技巧 >String、StringBuilder、StringBuffer三者的區別

String、StringBuilder、StringBuffer三者的區別

  StringBuffer、StringBuilder和String都可以用來代表字串。String類是不可變類,任何對String的改變都會引發新的String物件的生成;StringBuffer、StringBuilder則是可變類,任何對它所指代的字串的改變都不會產生新的物件。

這三個類之間的區別主要是在兩個方面:執行緒安全和執行速度。

  1、執行緒安全

  String 字串常量
  StringBuffer 字串變數(執行緒安全)
  StringBuilder 字串變數(非執行緒安全)
  簡要的說, String 型別和 StringBuffer 型別的主要效能區別其實在於 String 是不可變的物件, 因此在每次對 String 型別進行改變的時候其實都等同於生成了一個新的 String 物件,然後將指標指向新的 String 物件,所以經常改變內容的字串最好不要用 String ,因為每次生成物件都會對系統性能產生影響,特別當記憶體中無引用物件多了以後, JVM 的 GC 就會開始工作,那速度是一定會相當慢的。而如果是使用 StringBuffer 類則結果就不一樣了,每次結果都會對 StringBuffer 物件本身進行操作,而不是生成新的物件,再改變物件引用。所以在一般情況下我們推薦使用 StringBuffer ,特別是字串物件經常改變的情況下。

  如果一個StringBuffer物件在字串緩衝區被多個執行緒使用時,StringBuffer中很多方法可以帶有synchronized關鍵字,所以可以保證執行緒是安全的,但StringBuilder的方法則沒有該關鍵字,所以不能保證執行緒安全,有可能會出現一些錯誤的操作。所以如果要進行的操作是多執行緒的,那麼就要使用StringBuffer,但是在單執行緒的情況下,還是建議使用速度比較快的StringBuilder。

  2、執行速度

  執行速度,又叫做執行速度,三者的執行速度比較結果為:StringBuilder > StringBuffer > String

  String最慢的原因:String為字串常量,而StringBuilder和StringBuffer均為字串變數,即String物件一旦建立之後該物件是不可更改的,但後兩者的物件是變數,是可以更改的。以下面一段程式碼為例:

1 String str="abc";
2 System.out.println(str);
3 str=str+"de";
4 System.out.println(str);

  如果執行這段程式碼會發現先輸出“abc”,然後又輸出“abcde”,好像是str這個物件被更改了,其實,這只是一種假象罷了,JVM對於這幾行程式碼是這樣處理的,首先建立一個String物件str,並把“abc”賦值給str,然後在第三行中,其實JVM又建立了一個新的物件也名為str,然後再把原來的str的值和“de”加起來再賦值給新的str,而原來的str就會被JVM的垃圾回收機制(GC)給回收掉了,所以,str實際上並沒有被更改,也就是前面說的String物件一旦建立之後就不可更改了。所以,Java中對String物件進行的操作實際上是一個不斷建立新的物件並且將舊的物件回收的一個過程,所以執行速度很慢。

  而StringBuilder和StringBuffer的物件是變數,對變數進行操作就是直接對該物件進行更改,而不進行建立和回收的操作,所以速度要比String快很多。StringBuffer和StringBuilder相比較,StringBuffer是執行緒安全的可變字元序列,一般執行緒安全必然會帶來效率問題;而StringBuilder是執行緒不安全的可變的字元序列,執行比較快。

  另外,有時候我們會這樣對字串進行賦值

1 String str="abc"+"de";
2 StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
3 System.out.println(str);
4 System.out.println(stringBuilder.toString());

  這樣輸出結果也是“abcde”和“abcde”,但是String的速度卻比StringBuilder的反應速度要快很多,這是因為第1行中的操作和

  String str="abcde";

  是完全一樣的,所以會很快,而如果寫成下面這種形式

1 String str1="abc";
2 String str2="de";
3 String str=str1+str2;

  那麼JVM就會像上面說的那樣,不斷的建立、回收物件來進行這個操作了,速度就會很慢。

  3、應用場景

  String:適用於少量的字串操作的情況

  StringBuilder:適用於單執行緒下在字元緩衝區進行大量操作的情況

  StringBuffer:適用多執行緒下在字元緩衝區進行大量操作的情況

參考:

  https://www.cnblogs.com/su-feng/p/6659064.html

  http://blog.csdn.net/mad1989/article/details/26389541   https://www.cnblogs.com/xingzc/p/6277581.html