Java基礎(chǔ)-String

周末在做一道題的時(shí)候用了String.format來生成hash值踩寇,結(jié)果一直運(yùn)行時(shí)間過長窑业,于是就梳理下String相關(guān)的知識士修。

String.format("%09d%0d",i,j);//非常耗時(shí)

字符串是否相等

首先是看一個(gè)判斷String是否相等的問題

    String a = "hello";

    String b = "hello";

    System.out.println(a==b);
    // true

在第一次使用hello字符串時(shí)智什,會創(chuàng)建字符串并存入常量池中持灰,重復(fù)使用時(shí),就從常量池取出怎燥,于是再多的相同字符串的變量都是相等的瘫筐。

在創(chuàng)建了變量c,使用new String的方式铐姚,比較a和c

    String c = new String("hello");
    System.out.println(a==c);
    //false

我們首先是創(chuàng)建了String的引用策肝,然后再將String的引用指向常量池中的“hello”,所以結(jié)果是false隐绵。在IDE寫這條new語句時(shí)實(shí)際就提示了 'new String' is redundant 這種寫法是多余的之众。

String的類中提供了一個(gè)intern方法,注釋上說:

 * When the intern method is invoked, if the pool already contains a
 * string equal to this {@code String} object as determined by
 * the {@link #equals(Object)} method, then the string from the pool is
 * returned. Otherwise, this {@code String} object is added to the
 * pool and a reference to this {@code String} object is returned.

如果常量池中有這個(gè)String相等時(shí)就返回依许,否則將這個(gè)String的對象假如到常量池中并返回它的引用棺禾。這是一個(gè)忽略包裝的對象,直接從常量池中取到字符串的方法峭跳。

    System.out.println(a== c.intern());
    //true

運(yùn)行下代碼與預(yù)期相符膘婶。

字符串拼接問題

實(shí)際開發(fā)過程中我們經(jīng)常會拼接一些字符串用于展示。如 單價(jià):25元蛀醉。在一些開發(fā)規(guī)范中經(jīng)常告訴我們不要直接“+”的形式悬襟,用StringBuilder效率更高。我們就用代碼舉個(gè)例子試一下拯刁。

    long startTime = System.currentTimeMillis();
    String str = "";
    for (int i = 0; i < 10000; i++) {
        str += i;
    }

    System.out.println(System.currentTimeMillis() - startTime);

使用“+”的方式將0~9999共一萬個(gè)數(shù)字進(jìn)行拼接脊岳,時(shí)間大約500ms。
再換成StringBuilder的方式

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < 10000; i++) {
        builder.append(i);
    }

只需10ms垛玻,效率相差50倍逸绎。
我們通過javap查看字節(jié)碼來研究這個(gè)問題。

    4 new #3 <java/lang/StringBuilder>
    7 dup
    8 invokespecial #4 <java/lang/StringBuilder.<init>>
    11 astore_3
    12 iconst_0
    13 istore 4
    15 iload 4
    17 sipush 10000
    20 if_icmpge 36 (+16)
    23 aload_3
    24 iload 4
    26 invokevirtual #5 <java/lang/StringBuilder.append>
    29 pop
    30 iinc 4 by 1
    33 goto 15 (-18)

這是StringBuilder方式生成的字節(jié)碼夭谤,可以看到StringBuilder的創(chuàng)建棺牧,調(diào)用append方法,和循環(huán)(go 15)

接下來看“+”拼接的方式

     4 ldc #3   //給String賦值
     6 astore_3
     7 iconst_0
     8 istore 4
     10 iload 4
     12 sipush 10000
     15 if_icmpge 44 (+29)
     18 new #4 <java/lang/StringBuilder>    //創(chuàng)建StringBuilder
    21 dup
    22 invokespecial #5 <java/lang/StringBuilder.<init>>    //初始化StringBuilder
    25 aload_3
    26 invokevirtual #6 <java/lang/StringBuilder.append>    //擴(kuò)展str現(xiàn)在的值
    29 iload 4
    31 invokevirtual #7 <java/lang/StringBuilder.append>    //擴(kuò)展現(xiàn)在的i
    34 invokevirtual #8 <java/lang/StringBuilder.toString>  //toString轉(zhuǎn)回String
    37 astore_3
    38 iinc 4 by 1
    41 goto 10 (-31)

通過注釋可以看出朗儒,使用“+”號拼接字符串真是令人窒息的操作颊乘,每一次循環(huán)都需要?jiǎng)?chuàng)建一個(gè)StringBuilder,添加現(xiàn)有值醉锄,再append循環(huán)的i乏悄,最后還要轉(zhuǎn)回String賦值給str。

為什么使用StringBuilder的原因找到了恳不,接下來回到文章開頭檩小,看String.format究竟做了什么,本想也看下字節(jié)碼烟勋,看也看不懂规求。一步步下去找到 \java\util\Formatter.java筐付,大致就是正則找到需要替換的部分,然后循環(huán)去替換阻肿,而且又需要一堆異常判斷就比較耗時(shí)瓦戚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市丛塌,隨后出現(xiàn)的幾起案子较解,更是在濱河造成了極大的恐慌,老刑警劉巖赴邻,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件印衔,死亡現(xiàn)場離奇詭異,居然都是意外死亡姥敛,警方通過查閱死者的電腦和手機(jī)奸焙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來徒溪,“玉大人忿偷,你說我怎么就攤上這事‰冢” “怎么了鲤桥?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長渠概。 經(jīng)常有香客問我茶凳,道長,這世上最難降的妖魔是什么播揪? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任贮喧,我火速辦了婚禮,結(jié)果婚禮上猪狈,老公的妹妹穿的比我還像新娘箱沦。我一直安慰自己,他們只是感情好雇庙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布谓形。 她就那樣靜靜地躺著,像睡著了一般疆前。 火紅的嫁衣襯著肌膚如雪寒跳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天竹椒,我揣著相機(jī)與錄音童太,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛书释,可吹牛的內(nèi)容都是我干的翘贮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼征冷,長吁一口氣:“原來是場噩夢啊……” “哼择膝!你這毒婦竟也來了誓琼?” 一聲冷哼從身側(cè)響起检激,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腹侣,沒想到半個(gè)月后叔收,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡傲隶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年饺律,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跺株。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡复濒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乒省,到底是詐尸還是另有隱情巧颈,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布袖扛,位于F島的核電站砸泛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛆封。R本人自食惡果不足惜唇礁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惨篱。 院中可真熱鬧盏筐,春花似錦、人聲如沸砸讳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绣夺。三九已至吏奸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陶耍,已是汗流浹背奋蔚。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泊碑。 一個(gè)月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓坤按,卻偏偏與公主長得像窘拯,于是被迫代替她去往敵國和親其屏。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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

  • String String是JAVA中最常用的對象吗浩,就是這樣一個(gè)最常用最普通的對象腹忽,當(dāng)你深入研究時(shí)卻發(fā)現(xiàn)我們并不是...
    luoyoub閱讀 402評論 1 0
  • 首先来累,來一道String的考題,代碼如下: 先不著急給出答案窘奏,我們來一步一步得進(jìn)行分析嘹锁,爭取覆蓋String大部分...
    HRocky閱讀 298評論 0 0
  • 常量池 當(dāng)我們new一個(gè)String對象的時(shí)候,如果常量池中已經(jīng)存在着裹,則直接引用领猾,也就是此時(shí)只會創(chuàng)建一個(gè)對象,如果...
    16325閱讀 161評論 0 0
  • 其他更多java基礎(chǔ)文章:java基礎(chǔ)學(xué)習(xí)(目錄) 學(xué)習(xí)資料:String類API中文深入解析String#int...
    Hiwayz閱讀 985評論 0 1
  • 其他更多java基礎(chǔ)文章:java基礎(chǔ)學(xué)習(xí)(目錄) 距離上次寫文章已經(jīng)好一段時(shí)間了骇扇,主要是工作忙起來摔竿,看書的時(shí)間就...
    Hiwayz閱讀 709評論 0 0