String:適用于少量的字符串操作的情況
StringBuilder:適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況
StringBuffer:適用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況
字符串廣泛應(yīng)用 在Java 編程中,在 Java 中字符串屬于對象许布,Java 提供了?String 類來創(chuàng)建和操作字符串兴革。
需要注意的是,String的值是不可變的蜜唾,這就導(dǎo)致每次對String的操作都會生成新的String對象杂曲,這樣不僅效率低下,而且大量浪費有限的內(nèi)存空間袁余。
當(dāng)對字符串進(jìn)行修改的時候擎勘,需要使用 StringBuffer 和 StringBuilder 類。
和 String 類不同的是颖榜,StringBuffer 和 StringBuilder 類的對象能夠被多次的修改棚饵,并且不產(chǎn)生新的未使用對象。
StringBuilder 類在 Java 5 中被提出掩完,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問)噪漾。
由于 StringBuilder 相較于 StringBuffer 有速度優(yōu)勢,所以多數(shù)情況下建議使用 StringBuilder 類且蓬。然而在應(yīng)用程序要求線程安全的情況下欣硼,則必須使用 StringBuffer 類。
擴(kuò)展
1恶阴、String
(1)String的創(chuàng)建原理
????由于String在Java世界中使用過于頻繁诈胜,Java為了避免在一個系統(tǒng)中產(chǎn)生大量的String對象,引入了字符串常量池冯事。其運行機(jī)制是:創(chuàng)建一個字符串時耘斩,首先檢查池中是否有值相同的字符串對象,如果有則不需要創(chuàng)建直接從池中剛查找到的對象引用桅咆;如果沒有則新建字符串對象括授,返回對象引用,并且將新創(chuàng)建的對象放入池中。但是荚虚,通過new方法創(chuàng)建的String對象是不檢查字符串池的薛夜,而是直接在堆區(qū)或棧區(qū)創(chuàng)建一個新的對象,也不會把對象放入池中版述。上述原則只適用于通過直接量給String對象引用賦值的情況梯澜。
舉例:String str1 = "123"; //通過直接量賦值方式,放入字符串常量池
String str2 = new String(“123”);//通過new方式賦值方式渴析,不放入字符串常量池
注意:String提供了inter()方法晚伙。調(diào)用該方法時,如果常量池中包括了一個等于此String對象的字符串(由equals方法確定)俭茧,則返回池中的字符串咆疗。否則,將此String對象添加到池中母债,并且返回此池中對象的引用午磁。
(2) String的特性
不可變。是指String對象一旦生成毡们,則不能再對它進(jìn)行改變迅皇。不可變的主要作用在于當(dāng)一個對象需要被多線程共享,并且訪問頻繁時衙熔,可以省略同步和鎖等待的時間登颓,從而大幅度提高系統(tǒng)性能。不可變模式是一個可以提高多線程程序的性能红氯,降低多線程程序復(fù)雜度的設(shè)計模式挺据。
針對常量池的優(yōu)化。當(dāng)2個String對象擁有相同的值時脖隶,他們只引用常量池中的同一個拷貝扁耐。當(dāng)同一個字符串反復(fù)出現(xiàn)時,這個技術(shù)可以大幅度節(jié)省內(nèi)存空間产阱。
2 StringBuffer/StringBuilder
StringBuffer和StringBuilder都實現(xiàn)了AbstractStringBuilder抽象類婉称,擁有幾乎一致對外提供的調(diào)用接口;其底層在內(nèi)存中的存儲方式與String相同构蹬,都是以一個有序的字符序列(char類型的數(shù)組)進(jìn)行存儲王暗,不同點是StringBuffer/StringBuilder對象的值是可以改變的,并且值改變以后庄敛,對象引用不會發(fā)生改變;兩者對象在構(gòu)造過程中俗壹,首先按照默認(rèn)大小申請一個字符數(shù)組,由于會不斷加入新數(shù)據(jù)藻烤,當(dāng)超過默認(rèn)大小后绷雏,會創(chuàng)建一個更大的數(shù)組头滔,并將原先的數(shù)組內(nèi)容復(fù)制過來,再丟棄舊的數(shù)組涎显。因此坤检,對于較大對象的擴(kuò)容會涉及大量的內(nèi)存復(fù)制操作,如果能夠預(yù)先評估大小期吓,可提升性能早歇。
唯一需要注意的是:StringBuffer是線程安全的,但是StringBuilder是線程不安全的讨勤〖可參看Java標(biāo)準(zhǔn)類庫的源代碼,StringBuffer類中方法定義前面都會有synchronize關(guān)鍵字潭千。為此谱姓,StringBuffer的性能要遠(yuǎn)低于StringBuilder。
3 應(yīng)用場景
[A]在字符串內(nèi)容不經(jīng)常發(fā)生變化的業(yè)務(wù)場景優(yōu)先使用String類脊岳。例如:常量聲明、少量的字符串拼接操作等垛玻。如果有大量的字符串內(nèi)容拼接割捅,避免使用String與String之間的“+”操作,因為這樣會產(chǎn)生大量無用的中間對象帚桩,耗費空間且執(zhí)行效率低下(新建對象亿驾、回收對象花費大量時間)。
[B]在頻繁進(jìn)行字符串的運算(如拼接账嚎、替換莫瞬、刪除等),并且運行在多線程環(huán)境下郭蕉,建議使用StringBuffer疼邀,例如XML解析、HTTP參數(shù)解析與封裝召锈。
[C]在頻繁進(jìn)行字符串的運算(如拼接旁振、替換、刪除等)涨岁,并且運行在單線程環(huán)境下拐袜,建議使用StringBuilder,例如SQL語句拼裝梢薪、JSON封裝等蹬铺。