String與StringBuffer
String和StringBuffer的區(qū)別,網(wǎng)上資料可以說(shuō)是數(shù)不勝數(shù),但是看到這篇文章,感覺(jué)里面做的小例子很有代表性,所以轉(zhuǎn)一下,并自己做了一點(diǎn)總結(jié)。
在java中有3個(gè)類(lèi)來(lái)負(fù)責(zé)字符的操作。
1.Character 是進(jìn)行單個(gè)字符操作的,
2.String 對(duì)一串字符進(jìn)行操作。不可變類(lèi)。
3.StringBuffer 也是對(duì)一串字符進(jìn)行操作,但是可變類(lèi)。
String:
是對(duì)象不是原始類(lèi)型;為不可變對(duì)象,一旦被創(chuàng)建,就不能修改它的值;對(duì)于已經(jīng)存在的String對(duì)象的修改都是重新創(chuàng)建一個(gè)新的對(duì)象,然后把新的值保存進(jìn)去;String 是final類(lèi),即不能被繼承。
StringBuffer:
是一個(gè)可變對(duì)象,當(dāng)對(duì)他進(jìn)行修改的時(shí)候不會(huì)像String那樣重新建立對(duì)象;它只能通過(guò)構(gòu)造函數(shù)來(lái)建立(StringBuffer sb = new StringBuffer());不能通過(guò)付值符號(hào)對(duì)他進(jìn)行付值(如:sb = "welcome to here!";//這樣是錯(cuò)誤的);對(duì)象被建立以后,在內(nèi)存中就會(huì)分配內(nèi)存空間,并初始保存一個(gè)null.向StringBuffer中付值的時(shí)候可以通過(guò)它的append方法(如:sb.append("hello"))。
字符串連接操作中StringBuffer的效率要比String高:
eg:
String str = new String("welcome to ");
str += "here";
其處理步驟實(shí)際上是通過(guò)建立一個(gè)StringBuffer,然后調(diào)用append(),最后
再將StringBuffer.toSting();這樣的話String的連接操作就比StringBuffer多出了一些附加操作,當(dāng)然效率上要打折扣。
并且由于String 對(duì)象是不可變對(duì)象,每次操作Sting 都會(huì)重新建立新的對(duì)象來(lái)保存新的值.
這樣原來(lái)的對(duì)象就沒(méi)用了,就要被垃圾回收.這也是要影響性能的。
總結(jié): 如果在程序中需要對(duì)字符串進(jìn)行頻繁的修改連接操作的話.使用StringBuffer性能會(huì)更高。
另一處轉(zhuǎn)載:
String 類(lèi)型和StringBuffer 類(lèi)型的主要性能區(qū)別其實(shí)在于 String 是不可變的對(duì)象,因此在每次對(duì) String 類(lèi)型進(jìn)行改變的時(shí)候其實(shí)都等同于生成了一個(gè)新的 String 對(duì)象,然后將指針指向新的 String 對(duì)象,所以經(jīng)常改變內(nèi)容的字符串最好不要用 String ,因?yàn)槊看紊蓪?duì)象都會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響,特別當(dāng)內(nèi)存中無(wú)引用對(duì)象多了以后, JVM 的 GC 就會(huì)開(kāi)始工作,那速度是一定會(huì)相當(dāng)慢的。
而如果是使用 StringBuffer 類(lèi)則結(jié)果就不一樣了,每次結(jié)果都會(huì)對(duì) StringBuffer 對(duì)象本身進(jìn)行操作,而不是生成新的對(duì)象,再改變對(duì)象引用。所以在一般情況下我們推薦使用 StringBuffer ,特別是字符串對(duì)象經(jīng)常改變的情況下。而在某些特別情況下, 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í)間了。但大家這里要注意的是,如果你的字符串是來(lái)自另外的 String 對(duì)象的話,速度就沒(méi)那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
這時(shí)候 JVM 會(huì)規(guī)規(guī)矩矩的按照原來(lái)的方式去做, S1 對(duì)象的生成速度就不像剛才那么快了,一會(huì)兒我們可以來(lái)個(gè)測(cè)試作個(gè)驗(yàn)證。
在大部分情況下 StringBuffer > String
StringBuilder 是 JDK5.0 中新增加的一個(gè)類(lèi),它跟 StringBuffer 的區(qū)別看下面的介紹(來(lái)源 JavaWorld ):
Java.lang.StringBuffer 線程安全的可變字符序列。類(lèi)似于 String 的字符串緩沖區(qū),但不能修改。可將字符串緩沖區(qū)安全地用于多個(gè)線程。可以在必要時(shí)對(duì)這些方法進(jìn)行同步,因此任意特定實(shí)例上的所有操作就好像是以串行順序發(fā)生的,該順序與所涉及的每個(gè)線程進(jìn)行的方法調(diào)用順序一致。
每個(gè)字符串緩沖區(qū)都有一定的容量。只要字符串緩沖區(qū)所包含的字符序列的長(zhǎng)度沒(méi)有超出此容量,就無(wú)需分配新的內(nèi)部緩沖區(qū)數(shù)組。如果內(nèi)部緩沖區(qū)溢出,則此容量自動(dòng)增大。從 JDK 5.0 開(kāi)始,為該類(lèi)增添了一個(gè)單個(gè)線程使用的等價(jià)類(lèi),即 StringBuilder 。與該類(lèi)相比,通常應(yīng)該優(yōu)先使用 StringBuilder 類(lèi),因?yàn)樗С炙邢嗤牟僮鳎捎谒粓?zhí)行同步,所以速度更快。
但是如果將 StringBuilder 的實(shí)例用于多個(gè)線程是不安全的。需要這樣的同步,則建議使用 StringBuffer 。
在大部分情況下 StringBuilder > StringBuffer
因此,根據(jù)這個(gè)不等式的傳遞定理: 在大部分情況下
StringBuilder > StringBuffer > String
posted on 2009-08-25 22:19 肥仔 閱讀(773) 評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi): Web-后臺(tái)