五種字符串拼接的區(qū)別

String +=:將s+=”a”生成字節(jié)碼,反編譯之后,應(yīng)該是一下代碼:
String s=(new StringBuilder()).append(s).append(“a”).toString();
也就是說使用+=的時候是先將String轉(zhuǎn)成了StringBuilder,使用其的append方法進行處理,從內(nèi)存分配上來講,又是新給了一個String,然后指向這個新的字符串,與concat相比每次不僅新New出來一塊新的內(nèi)存,并且還new了一個新的StringBuilder對象

StringBuffer:StringBuffer對象是可以修改和擴充的,直接在堆里面給分配一塊內(nèi)存,每一次使用append方法的時候,就在這個內(nèi)存塊里面在添加一個a,所以相對String要快一些,但是與StringBuilder相比又要慢一些,這是因為StringBuffer是線程安全的,它的append方法是synchronized聲明的(意思是這個方法約么全部執(zhí)行成功,要么全部不成功),是線程安全的。通俗來講就是StringBuffe的append有三個步驟,lock,臨界區(qū),unclock這三步,由于StringBuffer是多線程的,所以在for循環(huán)使用append的時候會有多個線程都分配到項目,在cpu切換內(nèi)存執(zhí)行的時候有可能線程1正在臨界區(qū)添加數(shù)據(jù) ,但是還未進入到解鎖階段,這個時候如果cpu切換到另一個線程2執(zhí)行,線程2就會發(fā)現(xiàn)線程1沒有解鎖,所以線程2就會等待,等待下一次cpu切換到線程1 繼續(xù)執(zhí)行,直到線程2發(fā)現(xiàn)線程1解鎖,那么線程2就會先加鎖,以確保自己能夠執(zhí)行完成,StringBuilder的append方法不是synchronized聲明的,所以沒有加鎖和解鎖的過程,所以也就沒有線程2的等待過程,所以會相對快一些,但是線程是不安全的,容易造成數(shù)據(jù)丟失

StringBuilder: StringBuilder的append方法是直接進入臨界區(qū),當(dāng)cpu切換到當(dāng)前程序的時候,假如當(dāng)前cpu第一次執(zhí)行這個程序,第一次進入append的for循環(huán)的時候會講數(shù)據(jù)寫進去,然后更新一下count,表示已經(jīng)使用的字符個數(shù),也可以當(dāng)作下標index來看,然后當(dāng)下一次cpu切換到線程2的時候,就會往新的index里面放數(shù)據(jù),這種情況是基于前面那個線程把數(shù)據(jù)更行完成并且更新了新的index,但是有的時候當(dāng)cpu切換到一個新的線程的時候他有可能前面那個線程append的時候,數(shù)據(jù)填寫了,Index沒有更新,這個新的線程執(zhí)行append方法的時候酒還是會在之前的Index的位置去添加數(shù)據(jù),這就造成了之前那個線程添加的數(shù)據(jù)丟失,所以StringBuilder是線程不安全的,但是因為沒有等待的過程所以相對較快,從代碼上來講StringBuilder本身有一個字符數(shù)組,每一次append就是往這個數(shù)組里面添加數(shù)據(jù),同理StringBuffer也是一樣的

concat:是final修飾的類,是不可以被繼承以及被修改的,所以每一次s+=”a”的時候事實上是在每一個常量池里面新給一個內(nèi)存塊,每一次的+=都會給一個新的內(nèi)存,一個新的地址,然后這個變量s指向新的變量,如此十萬次就有了十萬給內(nèi)存塊被new出來,所以速度相對較慢,從代碼上來講就是每一次先創(chuàng)建一個字符串?dāng)?shù)組,長度是兩個待拼接字符串長度之和,再將兩個字符串的值復(fù)制到這個字符數(shù)組中,并且使用這個數(shù)組創(chuàng)建一個新的String對象并且返回,每次都new一個新的String,源代碼如下:
public String concat(String str){
int otherLen=str.length();
if(otherLen ==0){
return this;
}
Int len=value.length;
Char buf[]=Arrays.copyOf(value,len+otherLen);
Str.getChars(buf,len);
Return new String(buf,true);
}

StriingUtils.join:與String +=類似,也是使用了StringBuilder來進行操作,但是其中還有很多其他操作,所以耗時比較長,其實StriingUtils.join更加擅長處理字符串?dāng)?shù)組的拼接

所以以上五個方法執(zhí)行從0個到十萬個a的添加,時間上的長短排序如下:
StringBuilder < StringBuffer < concat < String += < StriingUtils.join

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 最先接觸編程的知識是在大學(xué)里面,大學(xué)里面學(xué)了一些基礎(chǔ)的知識,c語言,java語言,單片機的匯編語言等;大學(xué)畢...
    oceanfive閱讀 3,375評論 0 7
  • 《Java從小白到大?!芳堎|(zhì)版已經(jīng)上架了?。?! 由字符組成的一串字符序列,稱為“字符串”,在前面的章節(jié)中也多次用到...
    tony關(guān)東升閱讀 1,268評論 0 2
  • 很多職場新人都有這樣的疑惑:以前在上學(xué)的時候,明明學(xué)習(xí)很不錯,可是為什么進入職場后,就和別人拉開了差距,被人遠遠地...
    雞汁先生閱讀 351評論 2 1
  • 新買的背心是個兔子造型的…一早晨準備上學(xué)…兔子穿上高興的說“太可愛了,小兔子,我覺得我就像小兔子,我名字也是小兔子...
    雪花花簡簡書閱讀 160評論 0 0
  • 2017.03.06晚上飯后,丁先生第一次陪伴孩子與我去到江邊七星公園并至孩子玩完整個溜冰參與課程回! 感謝他的這...
    無悔飄落閱讀 215評論 0 0

友情鏈接更多精彩內(nèi)容