Java基礎之十三 字符串

第十三章 字符串

13.1 不可變String

String對象是不可變的。String類中每個看起來會修改String值得方法,實際上都是建立了一個全新得String對象,以包含修改後得字符串內容。java

13.2 無心識得遞歸

Java中每一個類從根本上都是繼承自Object,標準容器類天然也不例外。
使用toString()方法打印出對象得內存地址正則表達式

import java.util.ArrayList;
import java.util.List;

public class InfiniteRecursion
{
    public static void main(String[] args)
    {
        List<AAA> v = new ArrayList<AAA>();
        for (int i = 0; i < 10; i++)
            v.add(new AAA());
        System.out.println(v);
    }
}
class AAA
{
    public String toString()
    {
        return " InfiniteRecursion address: " + super.toString() + "\n";
    }
}

13.3 格式化輸出

printf("Row 1:[%d %f]\n",x,y);

佔位符稱做格式修飾符,它們說明了插入數據的位置,還說明了插入數據的類型。
format()與printf()是等價的。數組

13.3.3 Formatter類

當你建立一個Formatter對象的時候,須要向其構造器傳遞一些信息,告訴它最終結果在哪裏輸出。工具

import java.io.PrintStream;
import java.util.Formatter;

public class Turtle
{
    private String name;
    private Formatter f;
    public Turtle(String name, Formatter f) {
        this.name = name;
        this.f = f;
    }
    public void move(int x, int y) {
        f.format("%s The Turtle is at (%d,%d)\n", name, x, y);
    }
    public static void main(String[] args) {
        PrintStream outAlias = System.err;
        Turtle tommy = new Turtle("Tommy",
                new Formatter(System.err));
        Turtle terry = new Turtle("Terry",
                new Formatter(outAlias));
        tommy.move(0,0);
        terry.move(4,8);
        tommy.move(3,4);
        terry.move(2,5);
        tommy.move(3,3);
        terry.move(3,3);
    }
}

Formatter的構造器通過重載能夠接受多種輸出目的地,最經常使用的仍是PrintString(),OutputStream和File。測試

13.3.4 格式化說明符

%[argument_index$][flags][width][.precision]conversion
width用來控制一個域的最小尺寸。默認下,數據是右對齊,不過能夠經過使用「-」標誌來改變對齊方向。
precision指示最大大小。用於string表示字符最大數量,用於浮點表示小數部分要顯示出來的位數,不可用於整數。this

import java.util.*;
public class Receipt
{
    private static final int width=15;
    private double total = 0;
    private Formatter f = new Formatter(System.out);
    public void printTitle() {
        f.format("%-"+width+"s %"+(width-10)+"s %"+(width-5)+"s\n", "Item", "Qty", "Price");
        f.format("%-"+width+"s %5s %10s\n", "----", "---", "-----");
    }
    public void print(String name, int qty, double price) {
        f.format("%-15.15s %5d %10.2f\n", name, qty, price);
        total += price;
    }
    public void printTotal() {
        f.format("%-15s %5s %"+(width-5)+".2f\n", "Tax", "", total*0.06);
        f.format("%-15s %5s %10s\n", "", "", "-----");
        f.format("%-15s %5s %10.2f\n", "Total", "",
                total * 1.06);
    }
    public static void main(String[] args) {
        Receipt receipt = new Receipt();
        receipt.printTitle();
        receipt.print("Jack's Magic Beans", 4, 4.25);
        receipt.print("Princess Peas", 3, 5.1);
        receipt.print("Three Bears Porridge", 1, 14.29);
        receipt.printTotal();
    }
}

13.3.5 Formatter轉換

import java.math.*;
import java.util.*;
public class Conversion
{
    public static void main(String[] args) {
        Formatter f = new Formatter(System.out);

        char u = 'a';
        System.out.printf("%3s : %s\n","u","a");
        System.out.println("u = 'a'");
        f.format("s: %s\n", u);
        // f.format("d: %d\n", u);
        f.format("c: %c\n", u);
        f.format("b: %b\n", u);
        // f.format("f: %f\n", u);
        // f.format("e: %e\n", u);
        // f.format("x: %x\n", u);
        f.format("h: %h\n", u);

        int v = 121;
        System.out.println("v = 121");
        f.format("d: %d\n", v);
        f.format("c: %c\n", v);
        f.format("b: %b\n", v);
        f.format("s: %s\n", v);
        // f.format("f: %f\n", v);
        // f.format("e: %e\n", v);
        f.format("x: %x\n", v);
        f.format("h: %h\n", v);

        BigInteger w = new BigInteger("50000000000000");
        System.out.println(
                "w = new BigInteger(\"50000000000000\")");
        f.format("d: %d\n", w);
        // f.format("c: %c\n", w);
        f.format("b: %b\n", w);
        f.format("s: %s\n", w);
        // f.format("f: %f\n", w);
        // f.format("e: %e\n", w);
        f.format("x: %x\n", w);
        f.format("h: %h\n", w);

        double x = 179.543;
        System.out.println("x = 179.543");
        // f.format("d: %d\n", x);
        // f.format("c: %c\n", x);
        f.format("b: %b\n", x);
        f.format("s: %s\n", x);
        f.format("f: %f\n", x);
        f.format("e: %e\n", x);
        // f.format("x: %x\n", x);
        f.format("h: %h\n", x);

        Conversion y = new Conversion();
        System.out.println("y = new Conversion()");
        // f.format("d: %d\n", y);
        // f.format("c: %c\n", y);
        f.format("b: %b\n", y);
        f.format("s: %s\n", y);
        // f.format("f: %f\n", y);
        // f.format("e: %e\n", y);
        // f.format("x: %x\n", y);
        f.format("h: %h\n", y);

        boolean z = false;
        System.out.println("z = false");
        // f.format("d: %d\n", z);
        // f.format("c: %c\n", z);
        f.format("b: %b\n", z);
        f.format("s: %s\n", z);
        // f.format("f: %f\n", z);
        // f.format("e: %e\n", z);
        // f.format("x: %x\n", z);
        f.format("h: %h\n", z);
    }
}

13.3.6 string.format()

String.format()是一個static方法,它接受與Formatter.format()方法同樣的參數,但返回一個String對象。rest

public class DatabaseException extends Exception
{
    public DatabaseException(int transactionID, int queryID,
                             String message) {
        super(String.format("(t%d, q%d) %s", transactionID,
                queryID, message));
    }
    public static void main(String[] args) {
        try {
            throw new DatabaseException(3, 7, "Write failed");
        } catch(Exception e) {
            System.out.println(e);
        }
    }
}

String.format()內部也是建立了一個Formatter對象,而後將傳入的參數轉給Formatter。code

13.6 正則表達式

正則表達式提供一種徹底通用的方式,來解決字符串匹配,選擇,編輯和驗證。orm

13.6.1 基礎

使用split()方法分割字符串:對象

public class Splitting {
    public static String knights = "Then, when you have found the shrubbery, you must "
            + "cut down the mightiest tree in the forest... " + "with... a herring!";

    public static void split(String regex) {
        System.out.println(Arrays.toString(knights.split(regex)));
    }

    public static void main(String[] args) {
        split(" "); // Doesn't have to contain regex chars
        split("\\W+"); // Non-word characters
        split("n\\W+"); // 'n' followed by non-word characters
        QA7.getString();
        QA7.E9();
    }
}

使用String自帶的正則表達式工具替換:

public class Replacing {
    static String s = Splitting.knights;

    public static void main(String[] args) {
       System.out.println(s.replaceFirst("f\\w+", "located"));
       System.out.println(s.replaceAll("shrubbery|tree|herring", "banana"));
    }
}

13.6.2 建立正則表達式

下面每個表達式都能匹配字符串"Rudolph":

public class Rudolph {
    public static void main(String[] args) {
        for (String pattern : new String[] { "Rudolph", "[rR]udolph", "[rR][aeiou][a-z]ol.*", "R.*" })
            System.out.println("Rudolph".matches(pattern));
    }
}

咱們的目的並非編寫最難理解的正則表達式,而是儘可能編寫可以完成任務的最簡單的最必要的正則表達式。

13.6.3 量詞

量詞描述了一個模式吸取輸入文本的方式:

  • 貪婪型:
  • 勉強型:
  • 佔有型:

13.6.4 Pattern和Matcher

用static Pattern.compile()方法來編譯正則表達式,它會根據String類型的正則表達式生成一個Pattern對象,把你要檢索的字符串傳入Pattern對象的matcher()方法。matcher()方法會生成一個Matcher對象。
測試正則表達式,看它們是否匹配一個輸入字符串:

 
find()

Matcher.find()方法可用來查找多個匹配:

 

組是用括號劃分的正則表達式,能夠根據組的編號來引用某個組。組號爲0表示整個表達式,組號爲1表達被一對括號括起的組。

 
start()與end()

在匹配操做成功後,start()返回先前匹配的其實位置的索引,而end()返回所匹配的最後字符的索引加一的值。

 
Pattern標記

Pattern類的compile()方法還有一個版本,它接受一個參數,以調整匹配行爲:
Pattern Pattern.compile(String regex,int flag)
經過"或"操做符組合多個標記功能:

 

13.6.5 Split()

Split()方法將輸入字符串斷開成字符串對象數組。
按照通用邊界斷開文本:

 

13.6.6 替換操做

正則表達式特別便於替換文本。

 

13.6.7 reset()

經過reset()方法,將現有的Matcher對象應用於一個新的字符串序列:

 

13.6.8 正則表達式與Java I/O

輸出的是有匹配的部分以及匹配部分在行中的位置:

 

17.7 掃描輸入

使用Scanner類掃描輸入:

 

13.7.1 Scanner定界符

用正則表達式指定本身所需的定界符:

 

13.7.2 用正則表達式掃描

相關文章
相關標籤/搜索