String 是不可改變,定長;
StringBuffer, StringBuilder 是不定長,可改變.
注意:原本覺得StringBuilder 和StringBuffer 的equals 方法是能夠比較兩個字符串的內容是否相等,今天才發現不是這麼回事。這兩個類都直接繼承自Object ,而且沒有重寫equals 方法。java
Java代碼 程序員
若要比較內容是否相同,sb1.toString().equals(sb2.toString())編程
簡要的說, String 類型和 StringBuffer 類型的主要性能區別其實在於 String 是不可變的對象, 所以在每次對 String 類型進行改變的時候其實都等同於生成了一個新的 String 對象,而後將指針指向新的 String 對象,因此常常改變內容的字符串最好不要用 String ,由於每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了之後, JVM 的 GC 就會開始工做,那速度是必定會至關慢的。
而若是是使用 StringBuffer 類則結果就不同了,每次結果都會對 StringBuffer 對象自己進行操做,而不是生成新的對象,再改變對象引用。因此在通常狀況下咱們推薦使用 StringBuffer ,特別是字符串對象常常改變的狀況下。而在某些特別狀況下, String 對象的字符串拼接實際上是被 JVM 解釋成了 StringBuffer 對象的拼接,因此這些時候 String 對象的速度並不會比 StringBuffer 對象慢,而特別是如下的字符串對象生成中, String 效率是遠要比 StringBuffer 快的:安全
Java代碼 多線程
你會很驚訝的發現,生成 String S1 對象的速度簡直太快了,而這個時候 StringBuffer 竟然速度上根本一點都不佔優點。其實這是 JVM 的一個把戲,在 JVM 眼裏,這個app
String S1 = 「This is only a」 + 「 simple」 + 「test」; 其實就是:
String S1 = 「This is only a simple test」; 因此固然不須要太多的時間了。但你們這裏要注意的是,若是你的字符串是來自另外的 String 對象的話,速度就沒那麼快了,譬如:模塊化
Java代碼 性能
這時候 JVM 會規規矩矩的按照原來的方式去作測試
在大部分狀況下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer 線程安全的可變字符序列。一個相似於 String 的字符串緩衝區,但不能修改。雖然在任意時間點上它都包含某種特定的字符序列,但經過某些方法調用能夠改變該序列的長度和內容。可將字符串緩衝區安全地用 於多個線程。能夠在必要時對這些方法進行同步,所以任意特定實例上的全部操做就好像是以串行順序發生的,該順序與所涉及的每一個線程進行的方法調用順序一 致。
StringBuffer 上的主要操做是 append 和 insert 方法,可重載這些方法,以接受任意類型的數據。每一個方法都能有效地將給定的數據轉換成字符串,而後將該字符串的字符追加或插入到字符串緩衝區中。 append 方法始終將這些字符添加到緩衝區的末端;而 insert 方法則在指定的點添加字符。
例如,若是 z 引用一個當前內容是「start」 的字符串緩衝區對象,則此方法調用 z.append("le") 會使字符串緩衝區包含「startle」 ,而 z.insert(4, "le") 將更改字符串緩衝區,使之包含「starlet」 。
在大部分狀況下 StringBuilder > StringBufferui
java.lang.StringBuilde
java.lang.StringBuilder 一個可變的字符序列是5.0 新增的。此 類提供一個與 StringBuffer 兼容的 API ,但不保證同步。該類被設計用做 StringBuffer 的一個簡易替換,用在字符串緩衝區被單個線程使用的時候(這種狀況很廣泛)。若是可能,建議優先採用該類,由於在大多數實現中,它比 StringBuffer 要快。二者的方法基本相同。
經過非官方試驗測試,StringBuilder 和StringBuffer 的測試總結以下:
1 . 爲了得到更好的性能,在構造 StirngBuffer 或 StirngBuilder 時應儘量指定它的容量。固然,若是你操做的字符串長度不超過 16 個字符就不用了。
2 . 相同狀況下使用 StirngBuilder 相比使用 StringBuffer 僅能得到 10%~15% 左右的性能提高,但卻要冒多線程不安全的風險。而在現實的模塊化編程中,負責某一模塊的程序員不必定能清晰地判斷該模塊是否會放入多線程的環境中運行,所以:除非你能肯定你的系統的瓶頸是在 StringBuffer 上,而且肯定你的模塊不會運行在多線程模式下,不然仍是用StringBuffer 吧 J
3 . 用好現有的類比引入新的類更重要。不少程序員在使用 StringBuffer 時是不指定其容量的(至少我見到的狀況是這樣),若是這樣的習慣帶入 StringBuilder 的使用中,你將只能得到 10 %左右的性能提高(不要忘了,你可要冒多線程的風險噢);但若是你使用指定容量的 StringBuffer ,你將立刻得到 45% 左右的性能提高,甚至比不使用指定容量的StirngBuilder 都快 30% 左右。