String、StringBuilder躏精、StringBuffer

一渣刷、Java String 類——String字符串常量
字符串廣泛應用 在Java 編程中,在 Java 中字符串屬于對象矗烛,Java 提供了 String 類來創(chuàng)建和操作字符串辅柴。
需要注意的是,String的值是不可變的,這就導致每次對String的操作都會生成新的String對象碌嘀,這樣不僅效率低下涣旨,而且大量浪費有限的內(nèi)存空間。我們來看一下這張對String操作時內(nèi)存變化的圖:

image

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

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

image

對字符串進行修改的時候少梁,需要使用 StringBuffer 和 StringBuilder 類洛口。

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

StringBuilder 類和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問)。

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

三者的繼承結構

image

三者的區(qū)別

image

(1)字符修改上的區(qū)別(主要湘纵,見上面分析)

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

①String

String s = null;

String s = “abc”;

②StringBuffer

StringBuffer s = null; //結果警告: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)容就是字符串”

三、可變性上
String字符串的本質脖咐,就是在String類內(nèi)部維護了一個字符數(shù)組,并且這個數(shù)組被final修飾伤柄,因此String是不可變對象

   /** The value is used for character storage. */
    private final char value[];

StringBuffer和StringBuilder都繼承于AbstractStringBuilder,不過AbstractStringBuilder內(nèi)的字符數(shù)組是沒有被final修飾的,因此StringBuffer和StringBuilder對象是可變的

  /**
     * The value is used for character storage.
     */
    char[] value;

三文搂、線程安全上
由于String是不可變的适刀,很顯然String類是線程安全的,而StringBuffer和StringBuilder都繼承于AbstractStringBuilder的一些公共方法煤蹭,不過在重寫時笔喉,StringBuffer對這些方法加了同步鎖:

@Override
    public synchronized int length() {
        return count;
    }

    @Override
    public synchronized int capacity() {
        return value.length;
    }


    @Override
    public synchronized void ensureCapacity(int minimumCapacity) {
        super.ensureCapacity(minimumCapacity);
    }

    /**
     * @since      1.5
     */
    @Override
    public synchronized void trimToSize() {
        super.trimToSize();
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @see        #length()
     */
    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }

四取视、是否實現(xiàn)了equals和hashCode方法
String實現(xiàn)了equals()方法,和hashCode()方法常挚,可以看到equals方法是比較的值作谭,而不是引用。
奄毡,new String("java").equals(new String("java"))的結果為true折欠;

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

   public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

而StringBuffer沒有實現(xiàn)equals()方法和hashCode()方法,因此吼过,new StringBuffer("java").equals(new StringBuffer("java"))的結果為false锐秦,將StringBuffer對象存儲進Java集合類中會出現(xiàn)問題。
五盗忱、初始化方式
當創(chuàng)建String對象時酱床,可以利用構造方法String str = new String("Java")的方式來對其進行初始化,也可以直接用賦值的方式String s = "Java"來初始化趟佃。

而StringBuffer只能使用構造方法StringBuffer sb = new StringBuffer("hello")的方式初始化扇谣。

小結
綜上,在執(zhí)行效率方面闲昭,StringBuilder最高罐寨,StringBuffer次之,String最低序矩,
(1)如果要操作少量的數(shù)據(jù)用 String衩茸;

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

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

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幔烛,隨后出現(xiàn)的幾起案子啃擦,更是在濱河造成了極大的恐慌,老刑警劉巖饿悬,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件令蛉,死亡現(xiàn)場離奇詭異,居然都是意外死亡狡恬,警方通過查閱死者的電腦和手機珠叔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弟劲,“玉大人祷安,你說我怎么就攤上這事⊥闷颍” “怎么了汇鞭?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵凉唐,是天一觀的道長。 經(jīng)常有香客問我霍骄,道長台囱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任读整,我火速辦了婚禮簿训,結果婚禮上,老公的妹妹穿的比我還像新娘米间。我一直安慰自己强品,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布车伞。 她就那樣靜靜地躺著择懂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪另玖。 梳的紋絲不亂的頭發(fā)上困曙,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音谦去,去河邊找鬼慷丽。 笑死,一個胖子當著我的面吹牛鳄哭,可吹牛的內(nèi)容都是我干的要糊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼妆丘,長吁一口氣:“原來是場噩夢啊……” “哼锄俄!你這毒婦竟也來了?” 一聲冷哼從身側響起勺拣,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤奶赠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后药有,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毅戈,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年愤惰,在試婚紗的時候發(fā)現(xiàn)自己被綠了苇经。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡宦言,死狀恐怖扇单,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奠旺,我是刑警寧澤令花,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布阻桅,位于F島的核電站,受9級特大地震影響兼都,放射性物質發(fā)生泄漏嫂沉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一扮碧、第九天 我趴在偏房一處隱蔽的房頂上張望趟章。 院中可真熱鬧,春花似錦慎王、人聲如沸蚓土。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜀漆。三九已至,卻和暖如春咱旱,著一層夾襖步出監(jiān)牢的瞬間确丢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工吐限, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鲜侥,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓诸典,卻偏偏與公主長得像描函,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子狐粱,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容