String葛假、StringBuffer和StringBuilder的區(qū)別

1.String

String:字符串常量,字符串長度不可變滋恬。Java中String是immutable(不可變)的聊训。
用于存放字符的數(shù)組被聲明為final的,因此只能賦值一次恢氯,不可再更改带斑。

2.StringBuffer(JDK1.0)

StringBuffer:字符串變量(Synchronized,即線程安全)勋拟。如果要頻繁對字符串內(nèi)容進(jìn)行修改勋磕,出于效率考慮最好使用StringBuffer,如果想轉(zhuǎn)成String類型指黎,可以調(diào)用StringBuffer的toString()方法朋凉。
Java.lang.StringBuffer線程安全的可變字符序列。在任意時間點上它都包含某種特定的字符序列醋安,但通過某些方法調(diào)用可以改變該序列的長度和內(nèi)容杂彭。可將字符串緩沖區(qū)安全地用于多個線程吓揪。
StringBuffer 上的主要操作是 append 和 insert 方法亲怠,可重載這些方法,以接受任意類型的數(shù)據(jù)柠辞。每個方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串团秽,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中。append 方法始終將這些字符添加到緩沖區(qū)的末端叭首;而 insert 方法則在指定的點添加字符习勤。例如,如果 z 引用一個當(dāng)前內(nèi)容是“start”的字符串緩沖區(qū)對象焙格,則此方法調(diào)用 z.append("le") 會使字符串緩沖區(qū)包含“startle”图毕,而 z.insert(4, "le") 將更改字符串緩沖區(qū),使之包含“starlet”眷唉。

3.StringBuilder(JDK5.0)

StringBuilder:字符串變量(非線程安全)予颤。在內(nèi)部,StringBuilder對象被當(dāng)作是一個包含字符序列的變長數(shù)組冬阳。

java.lang.StringBuilder是一個可變的字符序列蛤虐,是JDK5.0新增的。此類提供一個與 StringBuffer 兼容的 API肝陪,但不保證同步驳庭。該類被設(shè)計用作 StringBuffer 的一個簡易替換,用在字符串緩沖區(qū)被單個線程使用的時候(這種情況很普遍)氯窍。

其構(gòu)造方法如下:

構(gòu)造方法 描述
StringBuilder() 創(chuàng)建一個容量為16的StringBuilder對象(16個空元素)
StringBuilder(CharSequence cs) 創(chuàng)建一個包含cs的StringBuilder對象嚷掠,末尾附加16個空元素
StringBuilder(int initCapacity) 創(chuàng)建一個容量為initCapacity的StringBuilder對象
StringBuilder(String s) 創(chuàng)建一個包含s的StringBuilder對象捏检,末尾附加16個空元素
在大部分情況下荞驴,StringBuilder > StringBuffer不皆。這主要是由于前者不需要考慮線程安全。

4.三者區(qū)別

String 類型和StringBuffer的主要性能區(qū)別:String是不可變的對象, 因此在每次對String 類型進(jìn)行改變的時候熊楼,都會生成一個新的 String 對象霹娄,然后將指針指向新的 String 對象,所以經(jīng)常改變內(nèi)容的字符串最好不要用 String 鲫骗,因為每次生成對象都會對系統(tǒng)性能產(chǎn)生影響策治,特別當(dāng)內(nèi)存中無引用對象多了以后搁廓, JVM 的 GC 就會開始工作,性能就會降低。

使用 StringBuffer 類時沥邻,每次都會對 StringBuffer 對象本身進(jìn)行操作,而不是生成新的對象并改變對象引用弄痹。所以多數(shù)情況下推薦使用 StringBuffer 罩引,特別是字符串對象經(jīng)常改變的情況下。

在某些特別情況下排苍, 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里传藏,自動做了如下轉(zhuǎn)換:
Java Compiler直接把上述第一條語句編譯為:

String s1 = “This is only a simple test”;

所以速度很快。但要注意的是彤守,如果拼接的字符串來自另外的String對象的話毯侦,Java Compiler就不會自動轉(zhuǎn)換了,速度也就沒那么快了具垫,例如:

String s2 = “This is only a”;
String s3 = “ simple”;
String s4 = “ test”;
String s1 = s2 + s3 + s4;

這時候侈离,Java Compiler會規(guī)規(guī)矩矩的按照原來的方式去做,String的concatenation(即+)操作利用了StringBuilder(或StringBuffer)的append方法實現(xiàn)做修,此時霍狰,對于上述情況,若s2饰及,s3蔗坯,s4采用String定義,拼接時需要額外創(chuàng)建一個StringBuffer(或StringBuilder)燎含,之后將StringBuffer轉(zhuǎn)換為String宾濒;若采用StringBuffer(或StringBuilder),則不需額外創(chuàng)建StringBuffer屏箍。

5.使用策略
1)基本原則:如果要操作少量的數(shù)據(jù)绘梦,用String 橘忱;單線程操作大量數(shù)據(jù),用StringBuilder 卸奉;多線程操作大量數(shù)據(jù)钝诚,用StringBuffer。

(2)不要使用String類的"+"來進(jìn)行頻繁的拼接榄棵,因為那樣的性能極差的凝颇,應(yīng)該使用StringBuffer或StringBuilder類,這在Java的優(yōu)化上是一條比較重要的原則疹鳄。例如:

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();

當(dāng)出現(xiàn)上面的情況時拧略,顯然我們要采用第二種方法,因為第一種方法瘪弓,每次循環(huán)都會創(chuàng)建一個String result用于保存結(jié)果垫蛆,除此之外二者基本相同(對于jdk1.5及之后版本)。
(3)為了獲得更好的性能腺怯,在構(gòu)造 StringBuffer 或 StringBuilder 時應(yīng)盡可能指定它們的容量袱饭。當(dāng)然,如果你操作的字符串長度(length)不超過 16 個字符就不用了瓢喉,當(dāng)不指定容量(capacity)時默認(rèn)構(gòu)造一個容量為16的對象宁赤。不指定容量會顯著降低性能。
(4)StringBuilder一般使用在方法內(nèi)部來完成類似"+"功能栓票,因為是線程不安全的决左,所以用完以后可以丟棄。StringBuffer主要用在全局變量中走贪。
(5)相同情況下使用 StringBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升佛猛,但卻要冒多線程不安全的風(fēng)險。而在現(xiàn)實的模塊化編程中坠狡,負(fù)責(zé)某一模塊的程序員不一定能清晰地判斷該模塊是否會放入多線程的環(huán)境中運行继找,因此:除非確定系統(tǒng)的瓶頸是在 StringBuffer 上,并且確定你的模塊不會運行在多線程模式下逃沿,才可以采用StringBuilder婴渡;否則還是用StringBuffer。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凯亮,一起剝皮案震驚了整個濱河市边臼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌假消,老刑警劉巖柠并,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡臼予,警方通過查閱死者的電腦和手機(jī)鸣戴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粘拾,“玉大人窄锅,你說我怎么就攤上這事“胗矗” “怎么了酬滤?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長寓涨。 經(jīng)常有香客問我,道長氯檐,這世上最難降的妖魔是什么戒良? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮冠摄,結(jié)果婚禮上糯崎,老公的妹妹穿的比我還像新娘。我一直安慰自己河泳,他們只是感情好沃呢,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拆挥,像睡著了一般薄霜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纸兔,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天惰瓜,我揣著相機(jī)與錄音,去河邊找鬼汉矿。 笑死崎坊,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洲拇。 我是一名探鬼主播奈揍,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赋续!你這毒婦竟也來了男翰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蚕捉,失蹤者是張志新(化名)和其女友劉穎奏篙,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡秘通,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年为严,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肺稀。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡第股,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出话原,到底是詐尸還是另有隱情夕吻,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布繁仁,位于F島的核電站涉馅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏黄虱。R本人自食惡果不足惜稚矿,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捻浦。 院中可真熱鬧晤揣,春花似錦、人聲如沸朱灿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盗扒。三九已至跪楞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間环疼,已是汗流浹背习霹。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留炫隶,地道東北人淋叶。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像伪阶,于是被迫代替她去往敵國和親煞檩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容