久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

String, StringBuffer, StringBuilder區(qū)別

 香山早秋 2012-03-07
  • String是非可變類,其對(duì)象為字符串常量,,不適合頻繁改變,,如插入(insert),刪除(delete),,添加(append)等,。
  • StringBuffer是可變類,其對(duì)象為可修改的字符序列,,比較適合用來(lái)頻繁的修改字符串,,比如常用的是添加(append);而且是線程安全的,。當(dāng)需要多次修改時(shí),,盡量用這個(gè)類,。
  具體地說(shuō),當(dāng)你使用String b = b+"aa";這樣的語(yǔ)句的時(shí)候b實(shí)際上已經(jīng)不是以前的那個(gè)對(duì)象,,JVM重新劃分了一塊內(nèi)存保存b+"aa"的結(jié)果,,并使b的指向這塊新內(nèi)存。對(duì)于StringBuffer來(lái)說(shuō),,b.append("aa");執(zhí)行以后b仍然使用的是以前的那塊內(nèi)存空間,。同時(shí),對(duì)于原來(lái)b指向的內(nèi)存還有內(nèi)存回收的問(wèn)題,。  
  • StringBuilder是可變類,但基于單線程的,,也就是說(shuō)多線程是不安全的,,其余和StringBuffer一樣。所以速度相對(duì)較快,,如果不涉及多線程,,建議使用這個(gè)。

String類是不可變類,,任何對(duì)String的改變都會(huì)引發(fā)新的String對(duì)象的生成,;而StringBuffer則是可變類,任何對(duì)它所指代的字符串的改變都不會(huì)產(chǎn)生新的對(duì)象.當(dāng)改變字符串內(nèi)容時(shí),,采用StringBuffer能獲得更好的性能,。既然是為了獲得更好的性能,那么采用StringBuffer能夠獲得最好的性能嗎,?答案是NO,!為什么?如果你讀過(guò)《Think in Java》,,而且對(duì)里面描述HashTable和HashMap區(qū)別的那部分章節(jié)比較熟悉的話,,你一定也明白了原因所在。對(duì),,就是支持線程同步保證線程安全而導(dǎo)致性能下降的問(wèn)題,。HashTable是線程安全的,很多方法都是synchronized方法,,而HashMap不是線程安全的,,但其在單線程程序中的性能比HashTable要高。StringBuffer和StringBuilder類的區(qū)別也在于此,,新引入的StringBuilder類不是線程安全的,,但其在單線程中的性能比StringBuffer高。將 StringBuilder 的實(shí)例用于多個(gè)線程是不安全的,。如果需要這樣的同步,,則建議使用 StringBuffer


一個(gè)String對(duì)象的長(zhǎng)度是固定的,不能改變它的內(nèi)容,或者是附加新的字符至String對(duì)象中,。您也許會(huì)使用+來(lái)串聯(lián)字符串以達(dá)到附加新字符或字符串的目的,,但+會(huì)產(chǎn)生一個(gè)新的String實(shí)例。如果程序?qū)@種附加字符串的需求很頻繁,,并不建議使用+來(lái)進(jìn)行字符串的串聯(lián),。在面向?qū)ο蟪绦蛟O(shè)計(jì)中,最好是能重復(fù)運(yùn)用已生成的對(duì)象,,對(duì)象的生成需要內(nèi)存空間與時(shí)間,,不斷地產(chǎn)生String實(shí)例是一個(gè)沒(méi)有效率的行為。
J2SE 5.0提供java.lang.StringBuilder類,,使用這個(gè)類所產(chǎn)生的對(duì)象默認(rèn)會(huì)有16個(gè)字符的長(zhǎng)度,,您也可以自行指定初始長(zhǎng)度。如果附加的字符超出可容納的長(zhǎng)度,,則StringBuilder對(duì)象會(huì)自動(dòng)增加長(zhǎng)度以容納被附加的字符,。如果有頻繁作字符串附加的需求,使用StringBuilder會(huì)讓程序的效率大大提高,。通過(guò)下面的簡(jiǎn)單測(cè)試程序就可以知道效能差距有多大,。
ü 范例6.5   AppendStringTest.java                                                       
public class AppendStringTest {
     public static void main(String[] args) {
         String text = "";

         long beginTime = System.currentTimeMillis();
         for(int i = 0; i < 10000; i++)
             text = text + i;
         long endTime = System.currentTimeMillis();
         System.out.println("執(zhí)行時(shí)間:" + (endTime - beginTime));

         StringBuilder builder = new StringBuilder("");
         beginTime = System.currentTimeMillis();
         for(int i = 0; i < 10000; i++)
             builder.append(String.valueOf(i));
         endTime = System.currentTimeMillis();
         System.out.println("執(zhí)行時(shí)間:" + (endTime - beginTime));
     }
}

在范例6.5中首先使用+來(lái)串聯(lián)字符串,使用System.currentTimeMillis()取得for循環(huán)執(zhí)行前,、后的系統(tǒng)時(shí)間,,這樣就可以得知for循環(huán)執(zhí)行了多久。以下是我的計(jì)算機(jī)上的測(cè)試數(shù)據(jù):

執(zhí)行時(shí)間:4641
執(zhí)行時(shí)間:16
可以看到執(zhí)行的時(shí)間差距很大,,這說(shuō)明了使用+串聯(lián)字符串所帶來(lái)的負(fù)擔(dān),。如果有經(jīng)常作附加字符串的需求,建議使用StringBuilder,。事實(shí)上就范例6.5來(lái)說(shuō),,第二個(gè)for循環(huán)執(zhí)行時(shí)間還可以更短,因?yàn)閍ppend()也可以接受基本數(shù)據(jù)類型,,所以不必特地使用String.valueOf()方法從int取得String,。改為以下的方式,執(zhí)行時(shí)間可以大幅縮短:
for(int i = 0; i < 10000; i++)
     builder.append(i);
使用StringBuilder最后若要輸出字符串結(jié)果,,可以用toString()方法,。可以使用length()方法得知目前對(duì)象中的字符長(zhǎng)度,,而capacity()可返回該對(duì)象目前可容納的字符容量,。另外,StringBuilder還有像insert()方法可以將字符插入指定的位置,,如果該位置以后有字符,,則將所有的字符往后移,;deleteChar()方法可以刪除指定位置的字符,而reserve()方法可以反轉(zhuǎn)字符串,。詳細(xì)的使用可以查詢java.lang.StringBuilder的API文件說(shuō)明,。
StringBuilder是J2SE 5.0才新增的類,在J2SE 5.0之前的版本若有相同的需求,,則使用java.lang.StringBuffer,。事實(shí)上,StringBuilder被設(shè)計(jì)為與StringBuffer具有相同的操作接口,。在單機(jī)非多線程(Multithread)的情況下使用StringBuilder會(huì)有較好的效率,,因?yàn)镾tringBuilder沒(méi)有處理同步(Synchronized)問(wèn)題。StringBuffer則會(huì)處理同步問(wèn)題,,如果StringBuilder會(huì)在多線程下被操作,,則要改用StringBuffer,讓對(duì)象自行管理同步問(wèn)題,。
 
String 字符串常量
StringBuffer 字符串變量(線程安全)
StringBuilder 字符串變量(非線程安全) 
 簡(jiǎn)要的說(shuō), String 類型和 StringBuffer 類型的主要性能區(qū)別其實(shí)在于 String 是不可變的對(duì)象, 因此在每次對(duì) String 類型進(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ì)開始工作,那速度是一定會(huì)相當(dāng)慢的,。
 而如果是使用 StringBuffer 類則結(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)的方式去做


在大部分情況下 StringBuffer > String 
StringBuffer 
Java.lang.StringBuffer線程安全的可變字符序列,。一個(gè)類似于 String 的字符串緩沖區(qū),但不能修改,。雖然在任意時(shí)間點(diǎn)上它都包含某種特定的字符序列,,但通過(guò)某些方法調(diào)用可以改變?cè)撔蛄械拈L(zhǎng)度和內(nèi)容。
可將字符串緩沖區(qū)安全地用于多個(gè)線程,??梢栽诒匾獣r(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 要快,。兩者的方法基本相同。


今天有空,,下了scjp的題目做做,,想起了一個(gè)本來(lái)想寫卻又沒(méi)寫的問(wèn)題。這個(gè)問(wèn)題幾乎已成為面試必問(wèn)題,,雖然答案很簡(jiǎn)單,,但回答出確又真正理解的人我覺(jué)得并不多,。

String與StringBuffer的區(qū)別?

如果你在網(wǎng)上一搜,,會(huì)有非常多的答案,,其中最多的就是String是不可變而StringBuffer是可變的,但是這可變與不可變究竟是什么意思呢,?如果你能用IDE進(jìn)行debug的話,,你就會(huì)發(fā)現(xiàn),String實(shí)例化以后所有的屬性都是final的,,而StringBuffer確不是,,這就是可變與不可變。下面引用SCJP的試題來(lái)解釋一下這個(gè)例子:

java 代碼
  1. public class Test {   
  2.    public static void stringReplace (String text) {   
  3.    text = text.replace('j' , 'i');    
  4.    }   
  5.       
  6.    public static void bufferReplace (StringBuffer text) {   
  7.    text = text.append("C");    
  8.    }   
  9.       
  10.     public static void main (String args[]) {    
  11.     String textString = new String ("java");    
  12.     StringBuffer textBuffer = new StringBuffer ("java");    
  13.        
  14.     stringReplace (textString);    
  15.     bufferReplace (textBuffer);    
  16.        
  17.     System.out.println (textString + textBuffer);    
  18.     }    
  19.     }   

答案是 javajavaC

這是因?yàn)榈谄咝衪ext = text.append ("C"),,append方法會(huì)改變text中的值,而text與textBuffer指向的地址是相同的,。因此會(huì)打印javaC

再舉個(gè)例子:

String a = "a";  //假設(shè)a指向地址0x0001

a = "b";//重新賦值后a指向地址0x0002,但0x0001地址中保存的"a"依舊存在,,但已經(jīng)不再是a所指向的,。

因此String的操作都是改變賦值地址而不是改變值操作

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多