1. 程式人生 > >圖解Java中String、StringBuffer和StringBuilder的區別

圖解Java中String、StringBuffer和StringBuilder的區別

圖解Java中String、StringBuffer和StringBuilder的區別
參考部落格:https://blog.csdn.net/weixin_41101173/article/details/79677982

一、Java中的 String 類——String 是字串常量
1、字串廣泛應用在Java 程式設計中,在Java中字串屬於物件,Java提供了String類來建立和操作字串。需要注意的是,String的值是不可變的,這就導致每次對String的操作都會生成新的String物件,這樣不僅效率低下,而且大量浪費有限的記憶體空間。我們來看一下這張對String操作時記憶體變化的圖:

2、我們可以看到,初始化String的值為“hello”。然後在這個字串後面加上新的字串“world”,這個過程是需要重新在堆記憶體中開闢記憶體空間的,最終得到了“hello world”字串也相應的需要開闢記憶體空間。這樣短短的兩個字串,卻需要開闢三次記憶體空間,不得不說這是對記憶體空間的極大浪費。為了應對經常性的字串相關操作,谷歌引入兩個新的類——StringBuffer類和StringBuilder類來對此種變化字串進行處理。

二、Java中的StringBuffer類和StringBuilder類——StringBuffer字串變數、StringBuilder字串變數

1、當對字串進行修改的時候,需要使用 StringBuffer 類和 StringBuilder 類。

2、和String類不同的是,StringBuffer類和 StringBuilder類的物件能夠被多次修改,並且不產生新的未使用物件。

StringBuilder類在Java5中被提出,它和StringBuffer類之間最大的不同在於:

StringBuffer類的方法是執行緒安全的,可以同步訪問,速度慢;StringBuilder類的方法不是執行緒安全的,不能同步訪問,速度快。

3、正是由於StringBuilder類相較於StringBuffer類有速度優勢,所以多數情況下建議使用StringBuilder類。然而在應用程式要求執行緒安全的情況下,則必須使用StringBuffer類。

4、三者的繼承結構如下圖所示:

5、三者的區別:

(1)字串修改上的區別:主要見上面分析。

(2)初始化上的區別:String可以空賦值,後者不行,報錯

String類:
String str = null;   
String str = “abc”;
 

StringBuilder類和StringBuffer類:
StringBuilder sb = null;    //結果警告:Null pointer access: The variable result can only be null at this location
StringBuilder sb = new StringBuilder();    //StringBuffer物件是一個空的物件
StringBuilder sb = new StringBuilder(“abc”);    //建立帶有內容的StringBuffer物件,物件的內容就是字串”
 
StringBuffer sb = null;    //結果警告:Null pointer access: The variable result can only be null at this location
StringBuffer sb = new StringBuffer();    //StringBuffer物件是一個空的物件
StringBuffer sb = new StringBuffer(“abc”);    //建立帶有內容的StringBuffer物件,物件的內容就是字串”
 

一、String、StringBuffer與StringBuilder之間區別
1、首先說執行速度,或者說是執行速度,在這方面執行速度快慢為:StringBuilder > StringBuffer > String

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

(2)以下面一段程式碼為例:

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

(3)而StringBuilder和StringBuffer的物件是變數,對變數進行操作就是直接對該物件進行更改,而不進行建立和回收的操作,所以速度要比String快很多。

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

String str="abc"+"de";
StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
System.out.println(str);
System.out.println(stringBuilder.toString());
這樣輸出結果也是“abcde”和“abcde”,但是String的速度卻比StringBuilder的反應速度要快很多。

這是因為第1行中的操作和 String str="abcde"; 是完全一樣的,所以會很快;而如果第一行寫成下面這種形式  String str1="abc";  String str2="de";  String str=str1+str2;  那麼JVM就會像上面說的那樣,不斷的建立物件、回收物件來進行這個操作了,速度就會很慢。

2、再來說執行緒安全

(1)線上程安全上,StringBuilder是執行緒不安全的,而StringBuffer是執行緒安全的。

如果一個StringBuffer物件在字串緩衝區被多個執行緒使用時,StringBuffer中很多方法可以帶有synchronized關鍵字,所以可以保證執行緒是安全的。但StringBuilder的方法則沒有該關鍵字,所以不能保證執行緒安全,有可能會出現一些錯誤的操作。

所以如果要進行的操作是多執行緒的,那麼就要使用StringBuffer;但是在單執行緒情況下,還是建議使用速度比較快的StringBuilder。

3、總結一下

String:適用於少量的字串操作的情況
StringBuilder:適用於單執行緒下在字元緩衝區進行大量操作的情況
StringBuffer:適用多執行緒下在字元緩衝區進行大量操作的情況
--------------------- 
作者:stormchenmeng 
來源:CSDN 
原文:https://blog.csdn.net/cmm0401/article/details/81735247 
版權宣告:本文為博主原創文章,轉載請附上博文連結!