String,StringBuilder谅年,StringBuffer
String 字符串常量茧痒,對(duì)一串字符進(jìn)行操作。不可變類融蹂。
StringBuffer 字符串變量(線程安全)旺订。也是對(duì)一串字符進(jìn)行操作,但是可變類超燃。
StringBuilder 字符串變量(非線程安全)区拳。也是對(duì)一串字符進(jìn)行操作,但是可變類意乓。
String:
是對(duì)象不是原始類型.
為不可變對(duì)象,一旦被創(chuàng)建,就不能修改它的值.
對(duì)于已經(jīng)存在的String對(duì)象的修改都是重新創(chuàng)建一個(gè)新的對(duì)象樱调,然后把新的值保存進(jìn)去.
String 是final類,即不能被繼承.
StringBuffer:
是一個(gè)可變對(duì)象届良,當(dāng)對(duì)他進(jìn)行修改的時(shí)候不會(huì)像String那樣重新建立對(duì)象
它只能通過構(gòu)造函數(shù)來建立笆凌,StringBuffer sb = new StringBuffer();
備注:不能通過賦值符號(hào)對(duì)他進(jìn)行賦值.
對(duì)象被建立以后,在內(nèi)存中就會(huì)分配內(nèi)存空間,并初始保存一個(gè)null.向StringBuffer中付值的時(shí)候可以通過它的append方法.
sb.append("hello");
字符串連接操作中StringBuffer的效率要比String高:
String str = new String("welcome to "); str += "here";
的處理步驟實(shí)際上是通過建立一個(gè)StringBuffer,讓侯調(diào)用append(),最后再將StringBuffer toSting();
這樣的話String的連接操作就比StringBuffer多出了一些附加操作,當(dāng)然效率上要打折扣.
并且由于String 對(duì)象是不可變對(duì)象,每次操作Sting 都會(huì)重新建立新的對(duì)象來保存新的值.
這樣原來的對(duì)象就沒用了,就要被垃圾回收.這也是要影響性能的.
看看以下代碼:
將26個(gè)英文字母重復(fù)加了5000次,
String tempstr = "abcdefghijklmnopqrstuvwxyz";
int times = 5000;
long lstart1 = System.currentTimeMillis();
String str = "";
for (int i = 0; i < times; i++) {
str += tempstr;
}
long lend1 = System.currentTimeMillis();
long time = (lend1 - lstart1);
System.out.println(time);
可惜我的計(jì)算機(jī)不是超級(jí)計(jì)算機(jī)士葫,得到的結(jié)果每次不一定一樣一般為 46687左右乞而。
也就是46秒。
我們?cè)倏纯匆韵麓a
String tempstr = "abcdefghijklmnopqrstuvwxyz";
int times = 5000;
long lstart2 = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < times; i++) {
sb.append(tempstr);
}
long lend2 = System.currentTimeMillis();
long time2 = (lend2 - lstart2);
System.out.println(time2);
得到的結(jié)果為 16 有時(shí)還是 0
所以結(jié)論很明顯为障,StringBuffer 的速度幾乎是String 上萬倍晦闰。當(dāng)然這個(gè)數(shù)據(jù)不是很準(zhǔn)確。因?yàn)檠h(huán)的次數(shù)在100000次的時(shí)候鳍怨,差異更大呻右。不信你試試。
根據(jù)上面所說:
str += "here";
的處理步驟實(shí)際上是通過建立一個(gè)StringBuffer,讓侯調(diào)用append(),最后
再將StringBuffer toSting();
所以str += "here";可以等同于
StringBuffer sb = new StringBuffer(str);
sb.append("here");
str = sb.toString();
所以上面直接利用"+"來連接String的代碼可以基本等同于以下代碼
String tempstr = "abcdefghijklmnopqrstuvwxyz";
int times = 5000;
long lstart2 = System.currentTimeMillis();
String str = "";
for (int i = 0; i < times; i++) {
StringBuffer sb = new StringBuffer(str);
sb.append(tempstr);
str = sb.toString();
}
long lend2 = System.currentTimeMillis();
long time2 = (lend2 - lstart2);
System.out.println(time2);
平均執(zhí)行時(shí)間為46922左右鞋喇,也就是46秒声滥。
在某些特別情況下, String 對(duì)象的字符串拼接其實(shí)是被 JVM 解釋成了 StringBuffer 對(duì)象的拼接侦香,所以這些時(shí)候 String 對(duì)象的速度并不會(huì)比 StringBuffer 對(duì)象慢落塑,而特別是以下的字符串對(duì)象生成中, String 效率是遠(yuǎn)要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你會(huì)很驚訝的發(fā)現(xiàn)罐韩,生成 String S1 對(duì)象的速度簡(jiǎn)直太快了憾赁,而這個(gè)時(shí)候 StringBuffer 居然速度上根本一點(diǎn)都不占優(yōu)勢(shì)。其實(shí)這是 JVM 的一個(gè)把戲散吵,在 JVM 眼里龙考,這個(gè)
String S1 = “This is only a” + “ simple” + “test”; 其實(shí)就是:
String S1 = “This is only a simple test”; 所以當(dāng)然不需要太多的時(shí)間了蟆肆。但大家這里要注意的是,如果你的字符串是來自另外的 String 對(duì)象的話晦款,速度就沒那么快了炎功,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
這時(shí)候 JVM 會(huì)規(guī)規(guī)矩矩的按照原來的方式去做
總結(jié): 如果在程序中需要對(duì)字符串進(jìn)行頻繁的修改連接操作的話.使用StringBuffer性能會(huì)更高
StringBuffer
Java.lang.StringBuffer線程安全的可變字符序列。一個(gè)類似于 String 的字符串緩沖區(qū)缓溅,但不能修改蛇损。雖然在任意時(shí)間點(diǎn)上它都包含某種特定的字符序列,但通過某些方法調(diào)用可以改變?cè)撔蛄械拈L(zhǎng)度和內(nèi)容坛怪。
可將字符串緩沖區(qū)安全地用于多個(gè)線程淤齐。可以在必要時(shí)對(duì)這些方法進(jìn)行同步酝陈,因此任意特定實(shí)例上的所有操作就好像是以串行順序發(fā)生的床玻,該順序與所涉及的每個(gè)線程進(jìn)行的方法調(diào)用順序一致。
StringBuffer 上的主要操作是 append 和 insert 方法沉帮,可重載這些方法锈死,以接受任意類型的數(shù)據(jù)。每個(gè)方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串穆壕,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中待牵。append 方法始終將這些字符添加到緩沖區(qū)的末端;而 insert 方法則在指定的點(diǎn)添加字符喇勋。
例如缨该,如果 z 引用一個(gè)當(dāng)前內(nèi)容是“start”的字符串緩沖區(qū)對(duì)象,則此方法調(diào)用 z.append("le") 會(huì)使字符串緩沖區(qū)包含“startle”川背,而 z.insert(4, "le") 將更改字符串緩沖區(qū)贰拿,使之包含“starlet”。
在大部分情況下 StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder一個(gè)可變的字符序列是5.0新增的熄云。此類提供一個(gè)與 StringBuffer 兼容的 API膨更,但不保證同步。該類被設(shè)計(jì)用作 StringBuffer 的一個(gè)簡(jiǎn)易替換缴允,用在字符串緩沖區(qū)被單個(gè)線程使用的時(shí)候(這種情況很普遍)荚守。如果可能,建議優(yōu)先采用該類练般,因?yàn)樵诖蠖鄶?shù)實(shí)現(xiàn)中矗漾,它比 StringBuffer 要快。兩者的方法基本相同薄料。