1.String對象不可變 String對象不可變,只讀。任何指向它的引用都不能改變它的內容。改變String內容意味著創建了一個新的String對象。 String 對象作為方法參數時都會複製一份引用(不是複製對象),而引用指向的對象一直呆在單一物理位置上。 2.重載操作符和StringBuild ...
1.String對象不可變
- String對象不可變,只讀。任何指向它的引用都不能改變它的內容。改變String內容意味著創建了一個新的String對象。
- String 對象作為方法參數時都會複製一份引用(不是複製對象),而引用指向的對象一直呆在單一物理位置上。
2.重載操作符和StringBuild
- + += 這2個符號作用於字元串和基本類型數據時意義不相同,Java只有這2個操作符被重載過。
2.1 拼接字元串 + += 編譯器會調用StringBuild來工作。
2.2 拼接字元串時編譯器會創建一個StringBuild對象來生成最終的String,並且調用append方法來拼接字元串,最後用toString輸出。(一條表達式生成一個StringBuild對象)
2.3 如果 + +=在迴圈內,就會生成多個StringBuild對象,影響性能。如果在迴圈外創建StringBuild對象迴圈內調用append方法,就會只有一個對象。
7.Object的toString方法輸出對象引用地址,所有類都繼承它,但大多數類覆寫了toString方法,用來輸出對象內容的字元串。
3.無意識的遞歸
- 列印對象引用會調用toString,this代表調用當前方法的引用,所以this在toString中會發生遞歸調用。
4.格式化輸出
4.1輸出流的兩種格式化輸出方法。
- printf( ) 這和C語言中的一樣,使用%d、%f、%s等占位符,但C語言中不能拼接字元串,Java可以。
- format()和printf( )一樣,printf()調用了format()方法
4.2 Formatter類
4.2.1 新的格式化輸出功能都由Formatter類提供。
4.2.2 創建Formatter對象要給構造器傳遞一些信息,告訴它最後輸出到哪。
4.2.3 格式化說明符
- %[argument_index$] [flags] [width] [.precision] conversion [ ] 內為可略內容
1. argument_index 是一個十進位整數, 2$表示使用參數列表的第2個參數 。
2. flags 是修改輸出格式的字元集。有效標誌的集合取決於轉換類型。
3. width 是一個非負十進位整數,至少達到多少長度,不夠用空格補齊,預設右對齊。
4. precision 是一個非負十進位整數,前面有個點,和width區分。通常用來限制字元數,表示最多多少位。
整數無法使用,String型輸出最大字元量,浮點型表示小數點位數,不足補0,超過四捨五入。
5. 浮點數 %f 預設輸出小數點後6位
6. %b 對於Boolean 和 boolean型可以準確輸出,對於其他類型只要不是null,就為true,0也是true。
4.2.4 靜態方法 String.format()返回一個String, 如果只使用一次format()方法,這個比較簡單。
5.正則表達式
5.1 String自帶的正則表達式工具
- s.split(regex) 將字元串從正則表達式匹配的地方割開,並返回String數組。
- s.matches(regex) 返回boolean值, 是否能匹配到正則。
- s.replaceFirst(regex a)將第一個匹配到的正則換為a. s.replaceAll(regex a)替換全部。
- 只使用一次正則表達式建議使用自帶的
5.2 創建正則表達式對象
5.2.1 創建一個正則表達式對象 Pattern p = Pattern.compile(regex);
Pattern 是 final 類 只能通過靜態方法它的compile創建對象。
5.2.2 Matcher m = p.matcher(string);
Matcher 同樣也是 final 類
Pattern對象的matcher方法接受一個字元串並生成一個 Matcher 匹配器對象 ,通過匹配器可以獲得字元串與正則的關係
5.2.3 匹配器的一些方法:
- m.matches() 整個字元串是否匹配正則
- m.lookingAt() 字元串的起始部分是否匹配
- m.find() 查找下一個匹配(下一個意味著有迭代行為)
- m.find(int start) 從指定位置開始匹配
- find 只負責匹配,不返回匹配到的結果,匹配到的結果由group()獲取。
5.3 組
- 組是用括弧劃分的正則表達式,由外向內,由左向右 編號0 1 2 3 。。。叫 組0,組1,組2 。。。
5.3.1 Matcher對象獲得組相關信息的方法
- public int groupCount() 返回組的數量,不包括組0
- public String group() 返回前一次的全匹配(組0)相當於group(0)
- public String group(int i ) 返回 前一次匹配期間指定組,若之前匹配成功,指定組未能匹配則返回null
- start(int group) 返回匹配到的指定組的起始位置索引。
- start()返回匹配到的正則起始索引。
- end(int group) 返回匹配到的指定組的最後一位索引再加一。
- end()返回匹配到的正則最後一位索引再加一。
6 Pattern標記
- Pattern.compile(regex,int flage) flage來自pattern類中的常量,可以調整匹配行為,是對正則式的一種約定。可是使用 | 組合多個標記。
- Pattern.CANON_EQ 兩個字元當且僅當它們的完全規範分解相匹配時,就認為它們是匹配的。
- Pattern.CASE_INSENSITIVE(?i) 預設情況下,大小寫不敏感的匹配假定只有US-ASCII字元集中的字元才能進行。這個標記允許模式匹配不必考慮大小寫(大寫或小寫)。通過指定UNICODE_CASE標記及結合此標記。基於Unicode的大小寫不滿乾的匹配就可以開啟了。
- Pattern.COMMENTS(?x) 在這種模式下,空格符將被忽略掉,並且以#開始直到行末的註釋也會被忽略掉。
- Pattern.DOTALL(?s) 在dotall模式中,表達式"." 匹配所有字元,包括終結符。預設情況下,”." 表達式不匹配行終結符。
- Pattern.MULTILINE(?m) 在多行模式下,表達式^和$分別匹配一行的開始和結束。^還匹配輸入字元串的開始,而$還匹配輸入字元串的結尾。預設情況下,這些表達式僅匹配輸入的完整字元串的開始和結束。
- Pattern.UNICODE_CASE(?u) 當指定這個標記, 並且開啟CASE_INSENSITIVE時,大小寫不敏感的匹配將按照與Unicode標準相一致的方式進行。預設情況下,大小寫不敏感的匹配假定只能在US-ASCII 字元集中的字元才能進行
- Pattern.UNIX_LINES(?d) 在這種模式下,在., ^和$行為中, 只識別行終結符\n
7 split()
- 切割字元串並返回切割後的字元串數組,一切split()方法底層都由Pattern的split()方法提供支持。
1.Pattern.compile(regex).split(String string);
2.Pattern.compile(regex).split(String string, int limit); 從第limit個開始不分割,包括limit。
8 替換
1.String自帶替換
- public String replaceFirst(String regex,String replacement) 只替換第一個匹配到的正則。
- public String replaceAll(String regex,String replacement) 替換全部。
2. Matcher 替換
- Pattern.compile(regex).matcher(str).replaceFirst(repl) // String 方法的底層實現。
- Pattern.compile(regex).matcher(str).replaceAll(repl) // String 方法的底層實現。
- appendReplacement(StringBuffer sb, String replacement) 漸進式替換
Pattern p = Pattern.compile("cat"); Matcher m = p.matcher("one cat two cats in the yard"); StringBuffer sb = new StringBuffer(); //用於接收被替換的部分 while (m.find()) { m.appendReplacement(sb, "dog"); //System.out.println(sb.toString()); } m.appendTail(sb); //把剩餘部分存入sb System.out.println(sb.toString());
//one dog
//one dog two dog
//one dog two dogs in the yard
3 reset()
- m. reset(string) 將Matcher對象應用與一個新的字元串,中途改變要匹配的字元串。
9 正則與IO
10 掃描輸入 Scanner
- 對輸入進行分詞
1.scanner構造器接受任何類型的輸入對象。
2.普通next()方法返回下一個string對象。
3.基本類型除char外的 nextXXX() 方法都返回對應類型的數字。
4.next方法只有找到一個完整的分詞後才返回,否則線程掛起等待。
5.hasNexXXX()方法判斷下一個分詞是否是需要的類型。
6.scanner預設對空字元串分割。
7.scanner.useDlimiter(regex) 使用正則對輸入分詞
8.scanner.dlimiter() 返回 當前正則匹配到的字元串,並作為Pattern對象。
9 正在掃描
- nextXXX( string)和hasNex(string)都可以傳入String進行匹配。(註意是匹配不是分詞)。也可以傳入string類型和pattern類型的正則進行匹配。
- 用正則匹配後調用scanner.match(),返回MatcherResult類型的掃描匹配結果。它包含了獲得的內容及捕獲組位置,通過group(i)獲得對應組信息。