Java編程思想10——String

1.不可變String

String 對(duì)象是不可變的。String類(lèi)中每一個(gè)看起來(lái)會(huì)修改String值的方法枕赵, 實(shí)際上都是創(chuàng)建了一個(gè)全新的String對(duì)象君纫, 以包含修改后的字符串內(nèi)容性昭。而最初的String對(duì)象則絲亳未動(dòng)涤躲。

對(duì)千一個(gè)方法而言报嵌, 參數(shù)是為該方法提供信息的虱咧, 而不是想讓該方法改變自己的。

2.重載+與StringBuilder

用千String的"+"與"+=" 是Java中僅有的兩個(gè)重載過(guò)的操作符锚国,而Java井不允許程序員重載任何操作符腕巡。

如果拿不準(zhǔn)該用哪種方式,隨時(shí)可以用javap來(lái)分析你的程序血筑。
StringBuilder是JavaSE5引人的绘沉,在這之前Java用的是StringBuffer。后者是線程安全的豺总,因此開(kāi)銷(xiāo)也會(huì)大些车伞,所以在JavaSE5/6中,字符串操作應(yīng)該還會(huì)更快一點(diǎn)园欣。

3.無(wú)意識(shí)的遞歸

Java中的每個(gè)類(lèi)從根本上都是繼承自O(shè)bject,標(biāo)準(zhǔn)容器類(lèi)自然也不例外帖世。因此容器類(lèi)都有 toString()方法,并且覆寫(xiě)了該方法沸枯,使得它生成的String結(jié)果能夠表達(dá)容器自身日矫,以及容器所 包含的對(duì)象。

public class InfiniteRecursion { 
  public String toString() { 
    return " InfiniteRecursion address: " + this + "\n": 
  }

這里發(fā)生了自動(dòng)類(lèi)型轉(zhuǎn)換绑榴,由InfiniteRecursion類(lèi)型轉(zhuǎn)換成String類(lèi)型哪轿。因?yàn)榫幾g器看到一個(gè)String對(duì)象后面跟著一個(gè)"+"'而再后面的對(duì)象不是String,于是編譯器試渚將this轉(zhuǎn)換成一個(gè)String。它怎么轉(zhuǎn)換呢翔怎,正是通過(guò)調(diào)用this上的toString()方法窃诉,千是就發(fā)生了遞歸調(diào)用。

如果你真的想要打印出對(duì)象的內(nèi)存地址赤套,應(yīng)該調(diào)用Object.toString()方法飘痛,這才是負(fù)責(zé)此任務(wù)的方法。所以容握,你不該使用this,而是應(yīng)該調(diào)用super.toString()方法宣脉。

4.String上的操作

當(dāng)需要改變字符串的內(nèi)容時(shí),String類(lèi)的方法都會(huì)返回一個(gè)新的 String對(duì)象剔氏。同時(shí)塑猖,如果內(nèi)容沒(méi)有發(fā)生改變,String的方法只是返回指向原對(duì)象的引用而已谈跛。這 可以節(jié)約存儲(chǔ)空間以及避免額外的開(kāi)銷(xiāo)羊苟。

5.格式化輸出

5.1 printf()

5.2 System.out.format()

format()與printf()是等價(jià)的残制。

5.3 Formatter類(lèi)

在Java中券腔,所有新的格式化功能都由java.util.Formatter類(lèi)處理刹孔。可以將Formatte看作一個(gè)翻譯器倔幼,它將你的格式化字符串與數(shù)據(jù)翻譯成需要的結(jié)果鸯匹。當(dāng)你創(chuàng)建一個(gè)Formatter對(duì)象的時(shí)候匾灶, 需要向其構(gòu)造器傳遞一些信息吆豹,告訴它最終的結(jié)果將向哪里輸出。

5.4 格式化說(shuō)明符

%[argument_index$] [flags] [width][.precision]conversion 

最常見(jiàn)的應(yīng)用是控制一個(gè)域的最小尺寸占遥,這可以通過(guò)指定width來(lái)實(shí)現(xiàn)俯抖。 Formatter對(duì)象 通過(guò)在必要時(shí)添加空格,來(lái)確保一個(gè)域至少達(dá)到某個(gè)長(zhǎng)度瓦胎。 在默認(rèn)的情況下芬萍,數(shù)據(jù)是右對(duì)齊,不過(guò)可以通過(guò)使用"-"標(biāo)志來(lái)改變對(duì)齊方向搔啊。
與width相對(duì)的是precision, 它用來(lái)指明最大尺寸柬祠。width可以應(yīng)用于各種類(lèi)型的數(shù)據(jù)轉(zhuǎn)換, 并且其行為方式都一樣负芋。 precision則不然漫蛔, 不是所有類(lèi)型的數(shù)據(jù)都能使用precision, 而且,應(yīng)用于不同類(lèi)型的數(shù)據(jù)轉(zhuǎn)換時(shí)旧蛾,precision的意義也不同莽龟。 在將precision應(yīng)用于String時(shí),它表示打印 String時(shí)輸出字符的最大數(shù)址锨天。 而在將precision應(yīng)用千浮點(diǎn)數(shù)時(shí)毯盈, 它表示小數(shù)部分要顯示出來(lái)的位數(shù)(默認(rèn)是6位小數(shù)), 如果小數(shù)位數(shù)過(guò)多則舍人病袄, 太少則在尾部補(bǔ)零搂赋。 由千整數(shù)沒(méi)有小數(shù)部分,所以precision無(wú)法應(yīng)用千整數(shù)益缠,如果你對(duì)整數(shù)應(yīng)用precision, 則會(huì)觸發(fā)異常脑奠。

5.5 Formatter轉(zhuǎn)換

5.6 String.format()

String.format()是一個(gè) static方法,它接受與Formatter.format()方法一樣的參數(shù)幅慌,但返回一個(gè)String對(duì)象宋欺。當(dāng)你只需使回用format()方法一次的時(shí)候,String.format()用起來(lái)很方便欠痴。

其實(shí)在String.format()內(nèi)部迄靠,它也是創(chuàng)建一個(gè)Formatter對(duì)象秒咨,然后將你傳人的參數(shù)轉(zhuǎn)給該Formatter喇辽。

6.正則表達(dá)式

正則表達(dá)式提供了一種完全通用的方式,能夠解決各種字符串處理相關(guān)的問(wèn)題:匹配雨席、選擇菩咨、編輯以及驗(yàn)證。

6.1 基礎(chǔ)

在Java中,\的意思是“我要插人一個(gè)正則表達(dá)式的反斜線抽米,所以其后的字符具有特殊的意義特占。例如,如果你想表示一位數(shù)字云茸,那么正則表達(dá)式應(yīng)該是\d是目。如果你想插人一個(gè)普通的反斜線,則應(yīng)該這樣\\标捺。不過(guò)換行和制表符之類(lèi)的東西只需使用單反斜線:\n\t懊纳。

在正則表達(dá)式中,括號(hào)有著將表達(dá)式分組的效果亡容,而豎直線|則表示或操作嗤疯。

String類(lèi)還自帶了一個(gè)非常有用的正則表達(dá)式工具--split()方法,其功能是“將字符串從正則表達(dá)式匹配的地方切開(kāi)闺兢∶浚”

6.2 創(chuàng)建正則表達(dá)式

完整請(qǐng)參考java.util.regex.Pattern

6.3 量詞

量詞描述了一個(gè)模式吸收輸入文本的方式:

  • 貪婪型:量詞總是貪婪的,除非有其他的選項(xiàng)被設(shè)置屋谭。 貪婪表達(dá)式會(huì)為所有可能的模式發(fā)現(xiàn)盡可能多的匹配脚囊。 導(dǎo)致此問(wèn)題的一個(gè)典型理由就是假定我們的模式僅能匹配第一個(gè)可能的字符組,如果它是貪婪的戴而,那么它就會(huì)繼續(xù)往下匹配凑术。
  • 勉強(qiáng)型:用問(wèn)號(hào)來(lái)指定, 這個(gè)址詞匹配滿足模式所需的最少字符數(shù)所意。 因此也稱(chēng)作懶惰的淮逊、 最少匹配的、 非貪婪的扶踊、 或不貪婪的泄鹏。
  • 占有型:目前, 這種類(lèi)型的懋詞只有在Java語(yǔ)言中才可用(在其他語(yǔ)言中不可用)秧耗,井且也更高級(jí)备籽,因此我們大概不會(huì)立刻用到它。 當(dāng)正則表達(dá)式被應(yīng)用于字符串時(shí)分井,它會(huì)產(chǎn)生相當(dāng)多的狀態(tài)车猬, 以便在匹配失敗時(shí)可以回溯。 而 “占有的“ 址詞并不保存這些中間狀態(tài)尺锚, 因此它們可以防止回溯珠闰。 它們常常用千防止正則表達(dá)式失控,因此可以使正則表達(dá)式執(zhí)行起來(lái)更有效瘫辩。

多數(shù)正則表達(dá)式操作都接受CharSequence類(lèi)型的參數(shù)伏嗜。

6.4 Pattern和Matcher

一般來(lái)說(shuō)坛悉,比起功能有限的String類(lèi),我們更愿意構(gòu)造功能強(qiáng)大的正則表達(dá)式對(duì)象承绸。只需導(dǎo)人Java.util.regex包裸影,然后用staticPattern.compile()方法來(lái)編譯你的正則表達(dá)式即可。它會(huì)根據(jù)你的String類(lèi)型的正則表達(dá)式生成一個(gè)Pattern對(duì)象军熏。接下來(lái)轩猩,把你想要檢索的字符串傳人 Pattern對(duì)象的matcher()方法。matcher()方法會(huì)生成一個(gè)Matcher對(duì)象荡澎,它有很多功能可用界轩。
Matcher

組(Groups)
組是用括號(hào)劃分的正則表達(dá)式,可以根據(jù)組的編號(hào)來(lái)引用某個(gè)組衔瓮。組號(hào)為0表示整個(gè)表達(dá)式浊猾, 組號(hào)1表示被第一對(duì)括號(hào)括起的組, 依此類(lèi)推热鞍。

6.5 split()

split()方法將輸入字符串?dāng)嚅_(kāi)成字符串對(duì)象數(shù)組葫慎。

6.6 替換操作

正則表達(dá)式特別便千替換文本,它提供了許多方法:replaceFirst(String replacement)以參 數(shù)字符串replacemen氓換掉第一個(gè)匹配成功的部分薇宠。replaceAll(Stringreplacement)以參數(shù)字符串replacement替換所有匹配成功的部分偷办。appendReplacement(StringBuffersbuf, String replacement)執(zhí)行漸進(jìn)式的替換,而不是像replaceFirst()和replaceAII()那樣只替換第一個(gè)匹配或全部匹配澄港。

6.7 reset()

通過(guò)reset()方法椒涯,可以將現(xiàn)有的Matcher對(duì)象應(yīng)用千一個(gè)新的字符序列。

6.8 正則表達(dá)式與Java I/O

7.掃描輸入

到目前為止回梧,從文件或標(biāo)準(zhǔn)輸人讀取數(shù)據(jù)還是一件相當(dāng)痛苦的事情废岂。一般的解決之道就是讀入讀入一行文本,對(duì)其進(jìn)行分詞狱意,然后使用Integer湖苞、Double等類(lèi)的各種解析方法來(lái)解析數(shù)據(jù)。

Java SE5新增了Scanner類(lèi)详囤, 它可以大大減輕掃描輸入的工作負(fù)擔(dān)财骨。

7.1 Scanner定界符

默認(rèn)是空白字符,但是可以通過(guò)正則表達(dá)式指定自己所需的定界符藏姐。

7.2 用正則表達(dá)式掃描

除了能夠掃描基本類(lèi)型之外隆箩,你還可以使用自定義的正則表達(dá)式進(jìn)行掃描,這在掃描復(fù)雜數(shù)據(jù)的時(shí)候非常有用羔杨。

8.StringTokenizer

在Java引入正則表達(dá)式和Scanner類(lèi)之前捌臊,分割字符串的唯一方法是使用StringTokenizer來(lái)分詞。 不過(guò)问畅,現(xiàn)在有了正則表達(dá)式和Scanner, 我們可以使用更加簡(jiǎn)單娃属、更加簡(jiǎn)潔的方式來(lái)完成同樣的工作了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末护姆,一起剝皮案震驚了整個(gè)濱河市矾端,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卵皂,老刑警劉巖秩铆,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異灯变,居然都是意外死亡殴玛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)添祸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)滚粟,“玉大人,你說(shuō)我怎么就攤上這事刃泌》踩溃” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵耙替,是天一觀的道長(zhǎng)亚侠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)俗扇,這世上最難降的妖魔是什么硝烂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮铜幽,結(jié)果婚禮上滞谢,老公的妹妹穿的比我還像新娘。我一直安慰自己除抛,他們只是感情好爹凹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著镶殷,像睡著了一般禾酱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绘趋,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天颤陶,我揣著相機(jī)與錄音,去河邊找鬼陷遮。 笑死滓走,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的帽馋。 我是一名探鬼主播搅方,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼比吭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了姨涡?” 一聲冷哼從身側(cè)響起衩藤,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涛漂,沒(méi)想到半個(gè)月后赏表,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匈仗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年瓢剿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悠轩。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡间狂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出火架,到底是詐尸還是另有隱情前标,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布距潘,位于F島的核電站炼列,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏音比。R本人自食惡果不足惜俭尖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洞翩。 院中可真熱鬧稽犁,春花似錦、人聲如沸骚亿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)来屠。三九已至虑椎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間俱笛,已是汗流浹背捆姜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迎膜,地道東北人泥技。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像磕仅,于是被迫代替她去往敵國(guó)和親珊豹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子簸呈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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