Java編程思想筆記13.字符串

一年又一年,字節(jié)跳動 Lark(飛書) 研發(fā)團(tuán)隊(duì)又雙叒叕開始招新生啦!
【內(nèi)推碼】:GTPUVBA
【內(nèi)推鏈接】:https://job.toutiao.com/s/JRupWVj
【招生對象】:20年9月后~21年8月前 畢業(yè)的同學(xué)
【報名時間】:6.16-7.16(提前批簡歷投遞只有一個月抓住機(jī)會哦?。?/h5>
【畫重點(diǎn)】:提前批和正式秋招不矛盾!面試成功,提前鎖定Offer;若有失利,額外獲得一次面試機(jī)會,正式秋招開啟后還可再次投遞。

點(diǎn)擊進(jìn)入我的博客

字符串操作是計算機(jī)程序設(shè)計中最常見的行為

13.1 不可變String

String底層是由char[]實(shí)現(xiàn)的,是不可變的。
看起來會改變String的方法,實(shí)際上都是創(chuàng)建了一個新的String對象,任何指向它的引用都不可能改變它本身的值。

13.2 重載“+”與StringBuilder

重載操作符的意思是,一個操作符被用于不同的類時,被賦予類特殊的含義(String++=是Java中僅有的兩個重載過的操作符,而且Java不允許程序員重載操作符)。
由于String的不可變性,如果你通過多個String相加生成一個String的時候,就需要產(chǎn)生多個中間對象,這造成了一定的效率問題。

StringBuilder的好處
  1. 使用String對字符串進(jìn)行操作時,編譯器會自動幫你轉(zhuǎn)成StringBuilder來進(jìn)行操作
  2. StringBuilder來操作字符串,編譯后的代碼通常會更加簡單,效率更高
  3. 如果字符串比較簡單,可以使用String讓編譯器為你構(gòu)造最終的字符串結(jié)果;如果要在循環(huán)中使用字符串,那么最好自己創(chuàng)建一個StringBuilder

13.3 無意識的遞歸

    @Override
    public String toString() {
        return "Test" + this;
    }

上述代碼中,由于字符串在拼接的時候會自動調(diào)用toString()方法,所以會無意思造成遞歸。
如果你想打印對象的內(nèi)存地址,應(yīng)該調(diào)用Object.toString()方法

13.4 String上的操作

13.5 格式化輸出

13.5.1 System.out.printf()

System.out.printf("%d%n", 123)這種輸入方式來自于C,使用特殊的占位符來表示數(shù)據(jù)將來的位置,這些占位符稱作格式修飾符。

13.5.2 System.out.format()

System.out.printf()是相同的。

13.5.3 Formatter類

在Java中,所有新的格式化功能都由java.util.Formatter類處理。
Formatter的構(gòu)造器經(jīng)過重載可以接受多種輸出目的地,不過最常用的還是PrintStreamOutputStreamFile。

13.5.4 格式化說明符

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

  • 可選的argument_index是一個十進(jìn)制整數(shù),用于表明參數(shù)在參數(shù)列表中的位置。第一個參數(shù)由1$引用,第二個參數(shù)由2$引用,依此類推(不要忘記$)。
  • 可選flags是修改輸出格式的字符集。有效標(biāo)志集取決于轉(zhuǎn)換類型。
  • 可選width是一個非負(fù)十進(jìn)制整數(shù),表明要向輸出中寫入的最少字符數(shù),不足則用空格代替。默認(rèn)數(shù)據(jù)是右對齊,可以通過-實(shí)現(xiàn)左對齊。
  • 可選precision是一個非負(fù)十進(jìn)制整數(shù),通常用來限制最大字符數(shù)。特定行為取決于轉(zhuǎn)換類型。
  • 所需conversion是一個表明應(yīng)該如何格式化參數(shù)的字符。給定參數(shù)的有效轉(zhuǎn)換集取決于參數(shù)的數(shù)據(jù)類型。

13.5.5 Formatter轉(zhuǎn)換

類型轉(zhuǎn)換字符

13.5.6 String.format()

該方法可以接受Formatter.format()方法一樣的參數(shù),但返回一個String對象。

13.6 正則表達(dá)式

正則表達(dá)式是一種強(qiáng)大而靈活的文本處理工具。使用正則表達(dá)式,我們能夠以編程的方式,構(gòu)造復(fù)雜的文本模式,并對輸入的字符串進(jìn)行搜索。一旦找到了匹配這些模式的部分,你就能夠隨心所欲地對它們進(jìn)行處理。

13.6.1 基礎(chǔ)

正則表達(dá)式就是以某種方式來描述字符串。

Java和其他語言對反斜線\的處理不同
  1. 正常反斜線\:我們需要的就是一個單純的反斜線,但Java(包括其他語言)中,反斜線也被用來當(dāng)作轉(zhuǎn)義字符,所以不能直接使用
  2. 文藝反斜線\\:第一個反斜線表示轉(zhuǎn)移,第二個表示正常的反斜線
  3. Java二逼反斜線\\\\:在正則表達(dá)式中,反斜線也需要轉(zhuǎn)義,這是如果要插入一條反斜線這需要這種寫法。四個反斜線的作用其實(shí)是兩兩一組,第一組的反斜線作為轉(zhuǎn)義符,第二組的反斜線是正常要插入的反斜線。
String中內(nèi)建的正則匹配方法
  • String#matches()
  • String#split()
  • String#replaceFirst()
  • String#replaceAll()

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

正則表達(dá)式完整構(gòu)造子列表,請參考java.util.regex.Pattern

字符
字符
字符類
字符類
邏輯操作符
邏輯操作符
邊界匹配符
邊界匹配符

13.6.3 量詞

量詞:描述了一個模式吸收輸入文本的方式:
  1. 貪婪型:默認(rèn)設(shè)置,貪婪表達(dá)式會為所有可能的模式發(fā)現(xiàn)盡可能多的匹配,導(dǎo)致此問題的一個經(jīng)典理由就是假定我們的模式僅能匹配第一個可能的字符組,如果它是貪婪的,那么它會繼續(xù)往下匹配;
  2. 勉強(qiáng)型:在貪婪型基礎(chǔ)上添加?,這個量詞匹配滿足模式所需的最少字符數(shù),又稱作最少匹配;
  3. 占有型:在貪婪型基礎(chǔ)上添加+,目前這種類型的量詞只有在Java中才可用并且也更高級,當(dāng)正則表達(dá)式被應(yīng)用于字符串時,它會產(chǎn)生相當(dāng)多的狀態(tài)以便在匹配失敗時可以回溯,而占有型量詞并不保存這些中間狀態(tài),因此它們可以防止回溯,它們被用來防止正則表達(dá)式失控,因此可以讓正則表達(dá)式執(zhí)行起來更有效。
    三種模式對比

13.6.4 Pattern和Matcher

由于String類功能有限,所以可以通過java.util.regex包下的類實(shí)現(xiàn)更加復(fù)雜的功能

一般使用方法
    // 1.構(gòu)建Pattern對象
    Pattern pattern = Pattern.compile("1[0-9]{10}");
    // 2.構(gòu)建Matcher對象
    Matcher matcher = pattern.matcher("18888888888");
    // 3.使用Matcher方法
    System.out.println(matcher.matches());
Pattern方法
    // 構(gòu)建Pattern對象
    Pattern pattern = Pattern.compile(regex);
    // 將字符串按照正則表達(dá)式分割
    pattern.split("18888888888");
    // 生成Matcher對象判斷是否匹配
    pattern.matcher("18888888888");
    // 直接驗(yàn)證正則表達(dá)式和字符串是否匹配
    Pattern.matches("1[0-9]{10}", "18888888888");
Pattern標(biāo)記

Pattern類的compile()方法還有另一個版本,它接受一個標(biāo)記參數(shù)數(shù),以調(diào)整匹配的行為:
Pattern Pattern.compile(String regex,int flag);。其中的flag來自以下Pattern類中的常量:

標(biāo)記參數(shù)

Matcher方法

組是用括號劃分的正則表達(dá)式,可以根據(jù)組的編號來引用某個組。組號為0表示整個表達(dá)式,組號1表示被第一對括號括起的組,依此類推。因此在下面這個表達(dá)式:A(B(C))D中有三個組,組0是ABCD,組1是BC,組2是C。

    // 整個字符串是否滿足表達(dá)式
    matcher.matches();
    // 判斷字符串中是否包含表達(dá)式
    matcher.lookingAt();
    // 遍歷字符串
    matcher.find();
    matcher.find(int start);
    // 返回前一次匹配的結(jié)果
    matcher.group();
    matcher.groupCount();
    // 返回前一次匹配操作中尋找到的組的起始索引
    matcher.start();
    // 返回前一次匹配操作中尋找到的組的最后一個字符加一的值
    matcher.end();
    // 替換所有
    matcher.replaceAll();
    // 替換第一個
    matcher.replaceFirst();
    // 漸進(jìn)式的替換
    matcher.appendReplacement();
    // 將現(xiàn)在Matcher用于一個新的字符串
    matcher.reset();

13.7 掃描輸入

到日前為止,從文件或標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)還是一件相當(dāng)痛普的事情。終于,Java SE5新增了Scanner類,它可以大大減輕掃描輸入的工作負(fù)擔(dān)。
Scanner有多個重載的構(gòu)造器,可以接受FilePathInputStreamStringReadable對象。Readable是Java SE5中新加入的一個接口,表示“具有read()方法的某種東西”。

13.7.1 Scanner的定界符

在默認(rèn)的情況下,Scanner根據(jù)空白字符對輸入進(jìn)行分詞,但是你可以用正則表達(dá)式指定自己所需的定界符:scanner.useDelimiter();。還有一個delimiter()方法,用來返回當(dāng)前正在作為定界符使用的Pattern對象。

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

    Scanner scanner = new Scanner(System.in);
    while (scanner.hasNext("(\\d+)@(\\w+)\\.(\\w+)")) {
        scanner.next("(\\d+)@(\\w+)\\.(\\w+)");
        MatchResult result = scanner.match();
        System.out.println("號碼:" + result.group(1));
        System.out.println("域名:" + result.group(2));
        System.out.println("后綴:" + result.group(3));
    }

Scanner可以接受Pattern作為參數(shù),可以掃描復(fù)雜的數(shù)據(jù)。
配合正則表達(dá)式掃描時要注意:它僅僅針對下一個輸入分詞進(jìn)行匹配,如果你的正則表達(dá)式中含有定界符,那永遠(yuǎn)都不可能匹配成功。

13.8 StringTokenizer

已過時!

最后編輯于
?著作權(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)容

  • 一、Java 簡介 Java是由Sun Microsystems公司于1995年5月推出的Java面向?qū)ο蟪绦蛟O(shè)計...
    子非魚_t_閱讀 4,543評論 1 44
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,537評論 19 139
  • 前言 最先接觸編程的知識是在大學(xué)里面,大學(xué)里面學(xué)了一些基礎(chǔ)的知識,c語言,java語言,單片機(jī)的匯編語言等;大學(xué)畢...
    oceanfive閱讀 3,376評論 0 7
  • 清早,一個朋友發(fā)來消息說剛看見喜歡的那個人發(fā)了朋友圈,那是他們分開的第十個月,心里恍如這個雨季,又開始難過,所以來...
    王坤玥兒閱讀 516評論 0 0
  • 知識是無窮無盡的,當(dāng)一個人去不斷學(xué)習(xí)的時候,才知道自己知道的太少太少,才會讓自己有自省的意識,所以一定要讓自己做一...
    思嘉123閱讀 665評論 0 1

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