JAVA中的String三兄弟

來源:互聯網
上載者:User

標籤:多線程   drp   java   

    在編寫Java程式時,我們經常需要對某些字串進行拼接,之前我們經常用“+”來拼接,但在Java中如果我們直接使用這種拼接方法,會建立很多String型的對象,這樣一來,系統就會因為過多的String型對象而對伺服器對象和系統效能造成很大的影響。所以,Java中有一種更好的拼接字串的方法:使用StringBuffer或StringBuilder。

一、String和StringBuffer

◎ String :是不可變類,任何對String的改變都會產生新的String對象。

    當我們使用String來拼接兩個字串時,我們可以執行下面的幾行代碼:

<span style="font-family:FangSong_GB2312;font-size:18px;">String a ="123";String b = "456";String c = a + b;</span>

 

    這樣拼接出來的字串為:123456。而在程式執行完畢時,我們會發現為了滿足程式執行的需要,系統在執行過程建立了a,b,c三個對象。也就是說,使用String的“+”方法來拼接字串時,會產生很多String類型的新對象,用來滿足程式調用和執行的需要。因此,當建立的對象過多,系統的效能和執行效率會因此而受到影響。

◎ StringBuffer:可變類,任何對它所指代的字串的改變都不會產生新的對象。

   使用StringBuffer執行兩個字串相加的操作過程:

<span style="font-family:FangSong_GB2312;font-size:18px;">    StringBuffer sb1 = new StringBuffer(str1);    sb1.append(str2);    String result1 = sb1.toString();</span>

   當這個過程執行完畢,我們所需要的內容只有result1這一個對象,而執行過程中間出現的sb1就已經是記憶體回收的目標了。這樣不僅僅避免了執行過程中建立的多個String對象,而且降低了CPU的利用度。

   此時,如果我們要實現sb1,sb2,sb3三個字串的拼接,我們只需要在剛才的基礎上,繼續執行便可:

<span style="font-family:FangSong_GB2312;font-size:18px;">StringBuffer sb2 = new StringBuffer(result1);sb2.append(str3);String result2 = sb2.toString();</span>

   這樣,對我們有用的就只有result2對象一個,其中產生的sb2和result1都已經成了系統回收的目標。如果繼續增大字串的數量,系統就會相應地產生若干個StringBuffer和String的垃圾對象。

   而Java中的垃圾首先是佔用記憶體的,然後Java的虛擬機器會請記憶體回收的線程來回收這些垃圾,這樣就又會出現CPU的損耗,同事這些垃圾對象產生的時候也會產生系統開銷,所以如果在一個迴圈中使用字串的“+”,導致的系統開銷將是不可忽略和不可估量的。

   但是相對於StringBuffer來進行字串串連的話,

<span style="font-family:FangSong_GB2312;font-size:18px;">StringBuffer sb = new StringBuffer();sb.append(str1);sb.append(str2);.....sb.append(strN);String result = sb.toString();</span>

   除去中間的一個StringBuffer對象最後會被拋棄掉,其他的都是有效對象,比起上面產生的一對垃圾,提高的效率不是一星半點鐘。

二、StringBuffer和StringBuilder

◎ StringBuffer

   StringBuffer:字串變數(Synchronized,即安全執行緒)。如果要頻繁對字串內容進行修改,出於效率考慮最好使用StringBuffer,如果想轉成String類型,可以調用StringBuffer的toString()方法。

   StringBuffer 上的主要操作有append和insert方法。

◎ StringBuilder 

    StringBuilder:字串變數(非安全執行緒)。在內部,StringBuilder對象被當作是一個包含字元序列的變長數組。java.lang.StringBuilder是一個可變的字元序列,是JDK5.0新增的。此類提供一個與 StringBuffer 相容的 API,但不保證同步。該類被設計用作 StringBuffer 的一個簡易替換,用在字串緩衝區被單個線程使用的時候(這種情況很普遍)。

二者比較

    在大部分情況下,對執行速度而言,StringBuilder > StringBuffer。因為前者不需要考慮安全執行緒問題。

三、三兄弟的優缺點  

    String 類型和StringBuffer的主要效能區別:String是不可變的對象, 因此在每次對String 類型進行改變的時候,都會產生一個新的 String 對象,然後將指標指向新的 String 對象,所以經常改變內容的字串最好不要用 String ,因為每次產生對象都會對系統效能產生影響,特別當記憶體中無引用對象多了以後, JVM 的 GC 就會開始工作,效能就會降低。

   使用 StringBuffer 類時,每次都會對 StringBuffer 對象本身進行操作,而不是產生新的對象並改變對象引用。所以多數情況下推薦使用 StringBuffer ,特別是字串對象經常改變的情況下。

   在某些特別情況下, String 對象的字串拼接其實是被 Java Compiler 編譯成了 StringBuffer 對象的拼接,所以這些時候 String 對象的速度並不會比 StringBuffer 對象慢,例如:

<span style="font-family:FangSong_GB2312;font-size:18px;">String s1 = “This is only a” + “ simple” + “ test”;  StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);  </span>

   產生 String s1對象的速度並不比 StringBuffer慢。其實在Java Compiler裡,自動做了如下轉換:

Java Compiler直接把上述第一條語句編譯為:

<span style="font-family:FangSong_GB2312;font-size:18px;">String s1 = “This is only a simple test”;  </span>

   所以速度很快。但要注意的是,如果拼接的字串來自另外的String對象的話,Java Compiler就不會自動轉換了,速度也就沒那麼快了。

   因此如果要操作少量的資料,使用String;

        單線程操作大量資料,使用StringBuilder;

        多線程操作大量資料,使用StringBuffer。

 

JAVA中的String三兄弟

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.