圖析:String,StringBuffer與StringBuilder的區(qū)別

一、Java String 類——String字符串常量

字符串廣泛應(yīng)用 在Java 編程中,在 Java 中字符串屬于對****象,Java 提供了String 類來****創(chuàng)建****和****操作****字符串。

需要注意的是,String的值是不可變的,這就導(dǎo)致每次對String的操作都會生成新的String對象,這樣不僅效率低下,而且大量浪費(fèi)有限的內(nèi)存空間。我們來看一下這張對String操作時內(nèi)存變化的圖:

image
image.gif

?

我們可以看到,初始String值為“hello”,然后在這個字符串后面加上新的字符串“world”,這個過程是需要重新在棧堆內(nèi)存中開辟內(nèi)存空間的,最終得到了“hello world”字符串也相應(yīng)的需要開辟內(nèi)存空間,這樣短短的兩個字符串,卻需要開辟三次內(nèi)存空間,不得不說這是對內(nèi)存空間的極大浪費(fèi)。為了應(yīng)對經(jīng)常性的字符串相關(guān)的操作,谷歌引入了兩個新的類——StringBuffer類和StringBuild類來對此種變化字符串進(jìn)行處理。

二、StringBuffer 和 StringBuilder 類——StringBuffer、StringBuilder字符串變量

**
image
image.gif

?**

當(dāng)對字符串進(jìn)行修改的時候,需要使用 StringBuffer 和 StringBuilder 類。

和 String 類不同的是,StringBuffer 和 StringBuilder 類的對象能夠被多次的修改,并且不產(chǎn)生新的未使用對象。

StringBuilder 類在 Java 5 中被提出,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問)。

由于 StringBuilder 相較于 StringBuffer 有速度優(yōu)勢,所以多數(shù)情況下建議使用 StringBuilder 類。然而在應(yīng)用程序要求線程安全的情況下,則必須使用 StringBuffer 類。

三者的繼承結(jié)構(gòu)

**
image
image.gif

?**

三者的區(qū)別

(1)字符修改上的區(qū)別(主要)

String:不可變字符串;

StringBuffer:可變字符串、效率低、線程安全;

StringBuilder:可變字符序列、效率高、線程不安全;

(2)初始化上的區(qū)別,****String可以空賦值,后者不行,報錯

①String

StringBuffer s = null;   

StringBuffer s = “abc”;   

②StringBuffer

StringBuffer s = null; //結(jié)果警告:Null pointer access: The variable result can only be null at this location

StringBuffer s = new StringBuffer();//StringBuffer對象是一個空的對象

StringBuffer s = new StringBuffer(“abc”);//創(chuàng)建帶有內(nèi)容的StringBuffer對象,對象的內(nèi)容就是字符串”
image.gif

小結(jié):(1)如果要操作少量的數(shù)據(jù)用 String;

(2)多線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù) StringBuffer;

(3)單線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù) StringBuilder(推薦使用)。

三、StringBuilder類在Android中運(yùn)用示例

(1)上官方文檔,StringBuilder,A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

The principal operations on a StringBuilder are theappend and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string builder. The append method always adds these characters atthe end of the builder; the insert method adds the characters at a specified point.

參考網(wǎng)址:<u>https://developer.android.google.cn/reference/java/lang/StringBuilder.html</u>

由上面的官方文檔,我們知道以下幾點(diǎn):

一個可變的字符序列。StringBuilder類提供一個與StringBuffer兼容的API,但不保證同步。該類被設(shè)計用作StringBuffer的一個簡單替換,用在字符串緩沖區(qū)被單個線程使用的時候(這種情況很普遍)。如果可能,建議優(yōu)先采用該類,因?yàn)樵诖蠖鄶?shù)實(shí)現(xiàn)種,它比StringBuffer要快

在StringBuilder上的主要操作時append和insert方法,可重載這些方法,以接收任意類型的數(shù)據(jù)。每個方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串,然后將該字符串的字符追加或插入到字符串生成器中,append方法始終將這些字符添加到生成器的末端,而insert方法則在指定的點(diǎn)添加字符。

例如,如果z引用一個當(dāng)前內(nèi)容為“start”的字符串的生成器對象,則該方法調(diào)用z.append("le")將使字符串生成器包含“startle”,而z.insert(4,"le")將更改字符串生成器,使之包含“startlet”。

通常,如果sb引用StringBuilder的實(shí)例,則sb.append(x)和sb.insert(sb.length(),x)具有相同的效果。每個字符串生成器都有一定的容量,只要字符串生成器包含的字符序列的長度沒有超出此容量,就無需分配新的內(nèi)容緩沖區(qū)。如果內(nèi)容緩沖區(qū)溢出,則此容量自動增大。

將StringBuilder的實(shí)例用于多個線程是不安全的。如果需要這樣的同步,則建議使用StringBuffer。

(2)上代碼,具體實(shí)現(xiàn)

new Thread(new Runnable){
    @Override
        public void run(){
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        try{
                URL url = new URL("http://www.baidu.com");
                connection = (HttpURLConnection)url.openConnection();
                connnection.setRequestMethod("GET");
                InputStream in = connection.getInputStream();
                //下面對獲取到的輸入流進(jìn)行讀取
                reader= new BufferedReader(new InputStreamReader(in));
                StringBuilder response = new(StringBuilder());
                String line;
                While ((line =reader.readLine())!= null ){
                    response.appen    d(line));
                }
            showResponse(reponse.toString())
        }
    }......

}
image.gif

上段代碼模擬的是向百度網(wǎng)請求數(shù)據(jù),然后對網(wǎng)站返回的數(shù)據(jù)流進(jìn)行讀取,最終應(yīng)用StringBuilder()進(jìn)行字符串?dāng)?shù)據(jù)的讀取和顯示。

總結(jié):末尾總是有福利,三者區(qū)別可參照下表:

image.png

說明:博主博客會同步發(fā)布到CSDN,歡迎閱讀

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

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

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