https://www.jianshu.com/p/8c724dd28fa4
概念:
1、用來處理字符串常用的類有3種:String、StringBuffer和StringBuilder
2、三者之間的區別:
都是final類,都不允許被繼承;
String類長度是不可變的,StringBuffer和StringBuilder類長度是可以改變的;
StringBuffer類是線程安全的,StringBuilder不是線程安全的;
String 和 StringBuffer:
1、String類型和StringBuffer類型的主要性能區別:String是不可變的對象,因此每次在對String類進行改變的時候都會生成一個新的string對象,然後將指針指向新的string對象,所以經常要改變字符串長度的話不要使用string,因爲每次生成對象都會對系統性能產生影響,特別是當內存中引用的對象多了以後,JVM的GC就會開始工作,性能就會降低;
2、使用StringBuffer類時,每次都會對StringBuffer對象本身進行操作,而不是生成新的對象並改變對象引用,所以多數情況下推薦使用StringBuffer,特別是字符串對象經常要改變的情況;
3、在某些情況下,String對象的字符串拼接其實是被Java Compiler編譯成了StringBuffer對象的拼接,所以這些時候String對象的速度並不會比StringBuffer對象慢,例如:
String s1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
生成 String s1對象的速度並不比 StringBuffer慢。其實在Java Compiler裏,自動做了如下轉換:
Java Compiler直接把上述第一條語句編譯爲:
String s2 = “This is only a”;
String s3 = “ simple”;
String s4 = “ test”;
String s1 = s2 + s3 + s4;
這時候,Java Compiler會規規矩矩的按照原來的方式去做,String的concatenation(即+)操作利用了StringBuilder(或StringBuffer)的append方法實現,此時,對於上述情況,若s2,s3,s4採用String定義,拼接時需要額外創建一個StringBuffer(或StringBuilder),之後將StringBuffer轉換爲String;若採用StringBuffer(或StringBuilder),則不需額外創建StringBuffer
StringBuilder
StringBuilder是5.0新增的,此類提供一個與 StringBuffer 兼容的 API,但不保證同步。該類被設計用作 StringBuffer 的一個簡易替換,用在字符串緩衝區被單個線程使用的時候(這種情況很普遍)。如果可能,建議優先採用該類,因爲在大多數實現中,它比 StringBuffer 要快。兩者的方法基本相同
使用策略
1、基本原則:如果要操作少量的數據,用String ;單線程操作大量數據,用StringBuilder ;多線程操作大量數據,用StringBuffer。
2、不要使用String類的”+”來進行頻繁的拼接,因爲那樣的性能極差的,應該使用StringBuffer或StringBuilder類,這在Java的優化上是一條比較重要的原則,例如:
String result = "";
for (String s : hugeArray) {
result = result + s;
}
// 使用StringBuilder
StringBuilder sb = new StringBuilder();
for (String s : hugeArray) {
sb.append(s);
}
String result = sb.toString();
當出現上面的情況時,顯然我們要採用第二種方法,因爲第一種方法,每次循環都會創建一個String result用於保存結果,除此之外二者基本相同
3、 StringBuilder一般使用在方法內部來完成類似”+”功能,因爲是線程不安全的,所以用完以後可以丟棄。StringBuffer主要用在全局變量中
4、相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒多線程不安全的風險。而在現實的模塊化編程中,負責某一模塊的程序員不一定能清晰地判斷該模塊是否會放入多線程的環境中運行,因此:除非確定系統的瓶頸是在 StringBuffer 上,並且確定你的模塊不會運行在多線程模式下,纔可以採用StringBuilder;否則還是用StringBuffer