1. 不可變String
String對象是不可變的,String類中每一個看起來會修改String值的方法,實際上都是創建了一個全新的String對象,例如:
public class Immutable { public static String upcase(String s) { return s.toUpperCase(); } public static void main(String[] args) { String str1 = "String1"; String str2 = upcase(str1); System.out.println(str1); System.out.println(str2); } }
當把str1傳給upcase()方法時,實際傳遞的是引用的一個拷貝。每當把String對象作爲方法的參數時,都會複製一份引用。可以給一個String對象加任意多的別名,指向它的任何引用都不可能改變它的值。用於String的"+"與"+="是Java中僅有的兩個重載過的操作符,而Java並不允許程序員重載任何操作符。操作符"+"可以用來連接String,例如:
String mango = "mango"; String s = "abc" + mango + "def" + 47; System.out.println(s);
2. String操作
以下是String對象具備的一些基本方法:
方法 | 參數 | 應用 |
---|---|---|
length() | String中字符的個數 | |
charAt() | Int索引 | 取得String索引位置上的char |
getChars(), getBytes() | 複製部分起點和終點索引,目標數組,目標數組起始索引 | 複製char或byte到目標數組 |
toCharArray() | 生成一個char[] | |
equals(), equalsIgnoreCase() | 進行比較的String | 比較兩個String內容是否相同 |
compareTo() | 進行比較的String | 按詞典順序比較String內容 |
contains() | 要搜索的CharSequence | String對象是否包含參數內容 |
contentEquals() | 進行比較的CharSequence或StringBuffer | String是否與參數內容完全一致 |
equalsIgnoreCase() | 進行比較的String | 忽略大小寫比較內容 |
regionMatcher() | 該String的索引偏移量,另一個String及索引偏移量,比較長度 | 所比較區域是否相等 |
startsWith() | 可能的起始String | String是否以此參數起始 |
endsWith() | 可能的後綴String | String是否以此參數做後綴 |
indexOf(), lastIndexOf() | char; char與起始索引; String; String與起始索引 | String是否包含參數 |
substring() | 起始索引,終點座標 | 返回參數指定的新子字符串 |
concat() | 要連接的String | 返回新的連接後的String對象 |
replace() | 要替換掉的字符,用來進行替換的新字符 | 返回替換後的新String對象 |
toLowerCase toUpperCase() | 返回改變大小寫的新String對象 | |
trim() | 返回刪除兩端空白新String對象 | |
valueOf() | Object; char[]; boolean; char; int; long; float; double | 返回一個表示參數內容的String |
intern() | 爲每個唯一字符序列生成引用 |
3. 格式化輸出
在Java中,所有新的格式化功能都由java.util.Formatter類處理,它將格式化字符串與數據轉譯成需要的結果。當創建一個Formatter對象的時候,需要向其構造器傳遞一些信息,例如:
public class Test { private String s; private Formatter f; public Test(String s, Formatter f) { this.s = s; this.f = f; } public void move(int x, int y) { f.format("%s at (%d, %d)\n", s, x, y); } public static void main(String[] args) { Test t = new Test("Point", new Formatter(System.out)); t.move(1, 2); } }
所有的格式化文本都將輸出到System.out,Formmatter的構造器經過重載可以接受多種輸出目的地,不過最常用的還是PrintStream()、OutputStream和File。在插入數據時,如果想要控制空格與對齊,需要更精細複雜的格式修飾符,語法如下:
%[argument_index$][flags][witdh][.precision]conversion
最常見的是控制一個域的最小尺寸,可以通過指定width實現,Formatter對象通過在必要時添加空格,來確保一個域至少達到某個長度,默認是右對齊的,可以通過使用'-'標誌來改變對齊方向。與width相對的是precision,它用來指明最大尺寸,在將precision應用於String時,它表示打印String時輸出字符的最大數量,而在將precision應用於浮點數時,它表示小數部分要顯示出來的位數。
下表包含了最常用的類型轉換:
d | 整數型(十進制) | e | 浮點數(科學計數) |
c | Unicode字符 | x | 整數(十六進制) |
b | Boolean值 | h | 散列碼(十六進制) |
s | String | % | 字符"%" |
f | 浮點數(十進制) |
4. 正則表達式
導入java.util.regex包,用static Pattern.compile()方法可以編譯正則表達式,它根據String類型的正則表達式生成一個Pattern對象,再把想要檢索的字符串傳入Pattern對象的matcher()方法,生成一個Matcher對象,例如:
public static void main(String[] args) { for(String arg : args) { Pattern p = Pattern.compile(arg); Matcher m = p.matcher(args[0]); while(m.find()) { System.out.println("Match " + m.group() + " at positions " + m.start() + "-" + (m.end() - 1)); } } } }
Matcher.find()方法可用來查找多個匹配,find()像迭代器一樣前向遍歷輸入字符串。
組是用括號劃分的正則表達式,可以根據組的編號來引用某個組,例如A(B(C))D中有三個組:組0是ABCD,組1是BC,組2是C。Machter對象提供一系列方法用以獲取組相關的相信:public int groupCount()返回該匹配器的模式中的分組數目,第0組不包括在內。public String group()返回前一次匹配操作的第0組(整個匹配)。public String group(int i)返回在前一次匹配操作期間指定的組號。
在匹配操作成功之後,start()返回先前匹配的起始位置的索引,而end()返回所匹配的最後字符的索引加一的值。匹配操作失敗後,調用start()或end()將會產生IllegalStateException。
Pattern類的compile()方法還有另一個版本,它接受一個標記參數,以調整匹配的行爲:
Pattern Pattern.compile(String regex, int flag)
其中的flag來自以下Pattern類中的常量:
編譯標記 | 效果 |
---|---|
Pattern.CANON_EQ | 兩個字符當且權當它們的完全規範分解相匹配時,就認爲它們是匹配的。 |
Pattern.CASE_INSENSITIVE(?i) | 允許模式匹配不必考慮大小寫。 |
Pattern.COMMENTS(?x) | 忽略空格符,並且以#開始直到行末的註釋也會被忽略掉。 |
Pattern.DOTALL(?s) | 在這個模式中,表達式"."匹配所有字符,包括行終結符。 |
Pattern.MULTILINE(?m) | 在多行模式下,表達式^和$分別匹配一行的開始和結束。^還匹配輸入字符串的開始,而$還匹配輸入字符串的結尾。 |
Pattern.UNICODE_CASE(?u) | 當指定這個標記並開戶CASE_INSENSITIVE時,大小寫不敏感的匹配將按照與Unicode標準相一致的方式進行。 |
Pattern.UNIX_LINES(?d) | 在.、^和$中,只識別行終結符\n。 |