『Java 語法基礎』String、StringBuffer 與 StringBuilder 的區別

BNTang發表於2024-03-18

第一點: 可變和適用範圍。String 物件是不可變的,而 StringBuffer 和 StringBuilder 是可變字元序列。每次對 String 的操作相當於生成一個新的 String 物件,而對 StringBuffer 和 StringBuilder 的操作是對物件本身的操作,而不會生成新的物件,所以對於頻繁改變內容的字串避免使用 String,因為頻繁的生成物件將會對系統效能產生影響。

String、StringBuffer 和 StringBuilder 這三者在處理字串時各有不同。String 型別是 Java 中的基本資料型別之一,它代表不可變的字元序列。這意味著一旦一個 String 物件被建立,那麼它所包含的字元序列就不能被更改了。

舉個例子,如果你想在一個字串後面加上另外一些文字,如果你是用 String 來處理,每次新增操作實際上都會在記憶體中建立一個新的 String 物件來儲存新的字元序列,舊的 String 物件則可能被垃圾回收機制回收(如果沒有其它引用指向它)。這個過程是隱形的,你看不到,但是它確實在發生,尤其是當有很多字串操作的時候,這會造成記憶體的浪費和額外的效能開銷。

相對於 String,StringBuffer 和 StringBuilder 是可變的字元序列。這意味著你可以直接在原有物件的基礎上新增新內容或者更改內容,而不需要每次都建立一個新的物件。這使得它們在處理需要頻繁修改內容的字串時更加高效。

那麼,它們兩個有什麼區別呢?

StringBuffer 是執行緒安全的,也就是說當多個執行緒同時試圖修改同一個 StringBuffer 物件時,它可以保證資料的正確性和一致性。而 StringBuilder 則沒有這種執行緒安全的保證,但是在單執行緒環境下,它的效能要優於 StringBuffer,因為它避免了執行緒安全帶來的效能開銷。

用一個簡單的比喻來理解這三者的區別: 如果把字串比作一束花束,那麼一個 String 就像是用一次性花瓶裝飾的花束。每當你想換一束花,你就需要一個新的花瓶。而 StringBuffer 和 StringBuilder 就像是可以重複使用的花瓶。你可以隨時往裡面新增新的花朵(字元),或者拿掉一些花朵,而不需要每次都換一個新的花瓶。如果你家裡只有你一個人(單執行緒),那麼用 StringBuilder 就足夠了,如果你家裡同時有很多人可能同時去改變這束花(多執行緒),那麼你可能就需要一個有更好鎖機制的花瓶,也就是 StringBuffer。

在實際開發中,如果一個字串不會被多個執行緒同時修改,那麼推薦使用 StringBuilder,因為它通常會給你帶來更好的效能;如果字串安全性是個問題,那麼你可能需要使用 StringBuffer。而當確定字串的內容在建立後不會再發生變化時,你可以使用 String。

第二點: 執行緒安全。String 由於有 final 修飾,是 immutable 的,安全性是簡單而純粹的。StringBuilder 和 StringBuffer 的區別在於 StringBuilder 不保證同步,也就是說如果需要執行緒安全需要使用 StringBuffer,不需要同步的 StringBuilder 效率更高。

想象一下你在一家餐廳裡做廚師,而字串就像是你正在準備的一道菜。

String 像是一家只接受外賣訂單的餐廳,顧客點了什麼菜,你就準備什麼,整個過程非常簡單和直接。一旦菜做好並打包好,就不能再改了——如果顧客想加點什麼調料或者改變一下,你需要重新準備一份新的菜。這種方式非常安全,因為每個訂單都是獨立處理,不會相互影響。

StringBuffer 就像一家忙碌的餐廳,有很多服務員和廚師同時工作。在這種環境下,你需要確保不會有兩個人同時去盛一樣的菜導致混亂。為此,餐廳裡有一個規則,就是在一個人準備某道菜的時候,其他人必須等他完成才能開始他們的工作。這就相當於執行緒安全,StringBuffer 就是這樣工作的,它有一套內建的機制來保證即使多個執行緒嘗試修改同一個字串,每個修改還是會被逐個順序地處理,不會造成混亂。

StringBuilder 在這個比喻中,就像是隻有一個廚師在廚房裡工作。由於同一時間只有他一個人在那裡,所以不需要擔心會有其他人跟他搶著去做同一件事。這就意味著他可以更加高效地工作,不需要等待也不需要遵守輪流的規則。在程式中,如果你知道只有一個執行緒會修改字串,那麼使用 StringBuilder 就足夠了,因為它不帶執行緒安全的額外開銷,因此可以更快地完成任務。

簡而言之,在需要考慮資料在多個執行緒之間共享並且可能同時被修改的情況下,為了保證資料的一致性和完整性,你就需要像 StringBuffer 這樣的執行緒安全的選項。如果沒有這種需要,那麼 StringBuilder 就是一個更快速的選擇。而 String 始終是不可變的,適合那些一旦建立就不需要修改的場景。

相關文章