String、StringBuilder、StringBuffer,誰性能最高?
一,前言
剛開始學(xué)習(xí)Java時(shí),作為只是C語言的小白,就為其中的字符串操作而感到震撼。在此之下,C語言在字節(jié)序中保存一個(gè)結(jié)尾的\ 0去表示字符串,想實(shí)現(xiàn)串聯(lián)拼接,還需要調(diào)用strcpy庫(kù)函數(shù)或者自己手動(dòng)去復(fù)制副本,非常麻煩,更別提其他復(fù)雜操作,而Java通過字符串類讓串聯(lián)操作變得十分簡(jiǎn)單和方便。此外,還有stringbuilder等這些類的輔助,那么本文就從String,StringBuiler和StringBuffer的區(qū)別開始,去探討Java中的字符串操作。
二,字符串,StringBuiler和StringBuffer
2.1字符串類
Java提供了String類來創(chuàng)建和操作字符串。在二進(jìn)制中可以看到,String類內(nèi)部的實(shí)現(xiàn)也是一個(gè)字節(jié)數(shù)組,這個(gè)數(shù)組是final類型的,因此String是不可變的對(duì)象,每次在對(duì)字符串類進(jìn)行改變的時(shí)候都會(huì)生成一個(gè)新的字符串對(duì)象,然后將指針指向新的字符串對(duì)象。
2.2 StringBuilder類
和字符串類不同的是,StringBuilder類的對(duì)象能夠被多次修改,并且不產(chǎn)生新的對(duì)象。這個(gè)特性的意義在于,如果我們進(jìn)行大量的字符串操作,使用字符串類就會(huì)產(chǎn)生很大的性能消耗,而StringBuilder就可以避免這個(gè)問題。
2.3 StringBuffer類
StringBuffer和StringBuiler之間的最大不同在于StringBuilder的方法不是線程安全的。
由于StringBuilder相比較于StringBuffer有速度優(yōu)勢(shì),所以多數(shù)情況下建議使用StringBuilder類。而在應(yīng)用程序中要求線程安全的情況下,則必須使用StringBuffer類。
2.4 String,StringBuilder和StringBuffer的比較(對(duì)比C / C ++)
| 操作類型 | 說明 | 是否可變 | 線程安全性 | 表現(xiàn) |
|---|---|---|---|---|
| Java中的String | 字符串類中使用final關(guān)鍵字修飾字符數(shù)組來保存字符串 | 不可變 | 線程安全 | 低 |
| Java中的StringBuffer | 字符串變量 | 可變 | 線程安全 | 一般 |
| Java中的StringBuilder | 字符串變量 | 可變 | 線程不安全 | 一般 |
| C / C ++中的char *操作 | char *是一個(gè)指針,可以指向一個(gè)字符串多重 | 可變 | 不可知 | 高 |
| C / C ++中的char數(shù)組 | 用一個(gè)字符編碼來保存字符串 | 不可變 | 不可知 | 高 |
| C / C ++中的字符串封裝類 | 字符串可以被看成以字符為元素的一種容器。 | 可變 | 并發(fā)讀操作是線程安全的 | 較高 |
三,各種字符串操作的效率測(cè)試
3.1 測(cè)試代碼
????????@Test
????public?void?test()?{
????????int?count?=?100000;
????????long?startTime?=?System.currentTimeMillis();
????????String?str?=?"";
????????for(int?i?=?0;?i????????????str?+=?i;
????????}
????????System.out.println("執(zhí)行"+count+"次??String?耗時(shí):"+?getRunTime(startTime));
????????startTime?=?System.currentTimeMillis();
????????StringBuilder?stringBuilder?=?new?StringBuilder("");
????????for?(int?i?=?0;?i?????????????stringBuilder.append(i);
????????}
????????System.out.println("執(zhí)行"+count+"次??StringBuilder?耗時(shí):"+?getRunTime(startTime));
????????startTime?=?System.currentTimeMillis();
????????StringBuffer?stringBuffer?=?new?StringBuffer("");
????????for?(int?i?=?0;?i?????????????stringBuffer.append(i);
????????}
????????System.out.println("執(zhí)行"+count+"次??StringBuffer?耗時(shí):"+?getRunTime(startTime));
????}3.2 測(cè)試結(jié)果
執(zhí)行100000次??String?耗時(shí):32s
執(zhí)行100000次??StringBuilder?耗時(shí):2ms
執(zhí)行100000次??StringBuffer?耗時(shí):4ms3.3 小結(jié)
可以看到String類的性能遠(yuǎn)低于StringBuiler和StringBuffer,而StringBuiler在本次測(cè)試中比Stringbuffer提高了50%的性能
四,Java字符串和正則表達(dá)式
4.1 測(cè)試代碼
?@Test
????public?void?test0(){
????????//郵政編碼
????????String?postCode?=?"[1-9]\\d{5}";
????????//區(qū)號(hào)-座機(jī)號(hào)碼
????????String?areaCode?=?"\\d{3}-\\d{8}|\\d{4}-\\d{7}";
????????//手機(jī)號(hào)碼
????????String?phone?=?"(?:13\\d|15\\d|18\\d)\\d{5}(\\d{3}|\\*{3})";
????????String?text?=?"郵政編碼:440834"+
??????????????????????"區(qū)號(hào)-座機(jī)號(hào)碼:?020-12345678"+
??????????????????????"手機(jī)號(hào):13536373839"+
??????????????????????"郵政編碼:440833"+
??????????????????????"區(qū)號(hào)-座機(jī)號(hào)碼:?010-12345678"+
??????????????????????"手機(jī)號(hào):13536373739";
????????Pattern?p?=?Pattern.compile(postCode);
????????Matcher?m?=?p.matcher(text);
????????System.out.println("文本中包含郵政編碼:");
????????while?(m.find()){
????????????System.out.println(m.group());
????????}
????????p?=?Pattern.compile(areaCode);
????????m=?p.matcher(text);
????????System.out.println("文本中包含區(qū)號(hào)-座機(jī)號(hào)碼:");
????????while?(m.find()){
????????????System.out.println(m.group());
????????}
????????p?=?Pattern.compile(phone);
????????m=?p.matcher(text);
????????System.out.println("文本中包含手機(jī)號(hào):");
????????while?(m.find()){
????????????System.out.println(m.group());
????????}
????}4.2 測(cè)試結(jié)果
文本中包含郵政編碼:
440834
123456
135363
440833
123456
135363
文本中包含區(qū)號(hào)-座機(jī)號(hào)碼:
020-12345678
010-12345678
文本中包含手機(jī)號(hào):
13536373839
13536373739五,總結(jié)
經(jīng)過測(cè)試和比較,可以看到Java中同為串聯(lián)操作,但由于背后實(shí)現(xiàn)的原理不同,形成的性能差異也是十分巨大,相當(dāng)于在之下,C / C ++中的串行操作性能更高。類的性能遠(yuǎn)低于StringBuiler和StringBuffer,而StringBuiler比Stringbuffer的性能稍微高一點(diǎn)。對(duì)性能的探究,最終還是要回到使用場(chǎng)景,可以進(jìn)行總結(jié),如果不涉及串聯(lián)操作,那么String類是首選,如果涉及的串行操作沒有線程安全問題,那么使用StringBuilder,如果涉及的串行操作存在線程安全問題,那么使用StringBuffer
來源:cnblogs.com/misterchaos/p/12782986.html
