[Java] 字符串

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()要搜索的CharSequenceString對象是否包含參數內容
contentEquals()進行比較的CharSequence或StringBufferString是否與參數內容完全一致
equalsIgnoreCase()進行比較的String忽略大小寫比較內容
regionMatcher()該String的索引偏移量,另一個String及索引偏移量,比較長度所比較區域是否相等
startsWith()可能的起始StringString是否以此參數起始
endsWith()可能的後綴StringString是否以此參數做後綴
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浮點數(科學計數)
cUnicode字符x整數(十六進制)
bBoolean值h散列碼(十六進制)
sString%字符"%"
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。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章