String、StringBuilder 和StringBuffer

        String類是final類,也即意味着String類不能被繼承,並且它的成員方法都默認爲final方法。在Java中,被final修飾的類是不允許被繼承的,並且該類中的成員方法都默認爲final方法。可以看出String類其實是通過char數組來保存字符串的。 “對String對象的任何改變都不影響到原對象,相關的任何change操作都會生成新的對象”。

StringBuilder 與 StringBuffer 區別

        StringBuilder 可變字符串,線程不太安全,但效率高,推薦使用。

        StringBuffer 可變字符串,線程安全,但效率低,不推薦使用。

        String 是不可變字符串,根據實時情況使用,在循環當中不要使用,因爲會產生好多的沒用字符串。

通過實際代碼來展示每個方法的用法

JDK 源碼分析

首先研究它的構造器

發現它調用了父類的構造器來完成初始化。去它的父類 AbstractStringBuilder 發現

注: char[] value 用來存儲字符,count 用來記錄 char[] value 中字符的實際個數

 

原來 StringBuilder 和 String 一樣也是通過初始化一個字符數組來存儲字符串的。

但注意 AbstractStringBuilder 的 char[] value 並沒有用 final 修飾,那就意味着這個是可變的字符數組。那這個數組是被初始化大小的,我們如何實現可以拼接很多字符串呢?StringBuilder 不是可以無限追加( append )字符串嗎?

其實這裏用到了擴容。什麼是擴容?就是當原數組已經裝不下新添加的內容時,這個時候創建一個新數組,將原數組的內容複製到新數組中,從而達到擴容的效果。

 append 方法分析

下面我們來看一看 append 這個方法。看一看 jdk 具體是怎麼實現擴容的。

我們發現 append 其實調用的是 父類 AbstractStringBuilder 的 append 方法。在父類中重載了很多 append 方法,在這裏我以 append(String str) 爲例進行講解

上面代碼的大體意思是:

如果 str 爲 null,那我就添加一個 "null" 字符串。

獲取 str 的長度。

驗證是否超出容器的大小

注:Arrays.copyOf 就是 jdk 提供的一個數組複製的靜態方法

將當前 AbstractStringBuilder 的 count (char[] value 裏實際字符的個數) + len (新添加的 str 的長度) 作爲 minimumCapacity,然後 minimumCapacity 和value.length (char[] value 數組的大小) 進行比較,如果 minimumCapacity 大於 value.length,則進行擴容,將原數組的數據複製到新創建的數組中。

此時AbstractStringBuilder 的 char[] value 指向了新數組的地址,原數組的地址沒有人引用,從而過後被垃圾回收機制回收。

注:   value.length << 1 ,左移一位相當與乘 2,並且這中位運算效率比較高。

可以看出新數組的大小一般爲原數組大小的 2 倍 + 2,如果原數組大小的 2 倍 + 2 都小於 minimumCapacity,那麼新數組的大小爲  minimumCapacity。

把 str 的內容追加到 AbstractStringBuilder 的 char[] value 中,通過數組的複製實現。(其實還是通過 System.arraycopy 這個方法實現)

修改 count (char[] value 中實際字符的個數)

返回該方法的對象引用,從而可以實現方法鏈。

相關面試題的回答

StringBuilder 與 StringBuffer 的區別;

StringBuilder 與 String 的區別。

1. StringBuilder效率高,線程不安全,StringBuffer效率低,線程安全。

2. String是不可變字符串,StringBuilder是可變字符串。爲什麼有這樣的差異,可以深入源碼去解析,比如String類內的 priver final  char  value[] 等方法的原因。

3. 如果是簡單的聲明一個字符串沒有後續過多的操作,使用 String,StringBuilder 均可,若後續對字符穿做頻繁的添加,刪除操作,或者是在循環當中動態的改變字符串的長度應該用 StringBuilder。使用 String 會產生多餘的字符串,佔用內存空間。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章