1. 程式人生 > >《JAVA程式設計思想》學習筆記---第十三章:字串

《JAVA程式設計思想》學習筆記---第十三章:字串

1,不可變String

String物件時不可變的,每一個看起來會修改String的方法,實際上都是建立了一個全新的String物件,而最初的String物件絲毫未動!

package com.str;

public class Immutable {

    public static String upcase(String s){
        return s.toUpperCase();
    }

    public static void main(String[] args) {
        String q = "howpy";
        System.out
.println(q); String qq = upcase(q); System.out.println(qq); System.out.println(q); } }

過載“+”與StringBuilder

“+”可用於String:

package com.str;

public class Concatenation {

    public static void main(String[] args) {
        String mango = "mango";
        String s = "abc"
+mango+"def"+47; System.out.println(s); } }

這種進行字串的拼接,其實在底層編譯器會把String替換成StringBuilder來提高效率。
這種一次性的操作字串可以使用String,編譯器會幫助我們替換,不過在迴圈中操作字串可以手動替換為StringBuilder來提高效率!
StringBuilder有佷多豐富而全面的方法!

package com.str;

import java.util.*;

public class UsingStringBuilder {

    public static Random rand = new
Random(47); public String toString(){ StringBuilder result = new StringBuilder("["); for(int i = 0; i < 25;i++){ result.append(rand.nextInt(100)); result.append(","); } result.delete(result.length()-1,result.length()); result.append("]"); return result.toString(); } public static void main(String[] args) { UsingStringBuilder usb = new UsingStringBuilder(); System.out.println(usb); } }

3,無意識的遞迴

java每個類都整合Object,因此容器類都有toString()方法,並且重寫了該方法,這使得他生成的String結果能夠表達容器自身。
當使用ArrayList.toString()方法時,它會遍歷ArrayList中包含的所有變數,並且呼叫每個元素的toString()方法!

package com.str;

import java.util.*;

public class ArrayListDisplay {

    public String toString(){
        return "toString";
    }

    public static void main(String[] args) {
        List<ArrayListDisplay> a = new ArrayList<>();
        for(int i  = 0; i< 10; i++){
            a.add(new ArrayListDisplay());
        }
        System.out.println(a);
    }

}

當希望toString()方法列印物件的記憶體地址,也許你會烤爐使用this關鍵字,像下面這樣:

        return "toString"+this;
    }

執行時,會報一大堆錯。因為使用+號時,編譯器會將ArrayListDisplay強制轉換為String。
正確的方式是呼叫Object.toString()方法!

public String toString(){
        return "toString"+super.toString();
    }

4,String上的操作

一系列的方法

5,格式化輸出

5.1,printf()

java有和c語言一樣的格式化輸出語句printf(),

package com.str;

public class Printf {

    public static void main(String[] args) {
        int i = 1;
        System.out.printf("i=%d",i);
    }

}

5.2,System.out.format()

format與printf()一樣

5.3,Formatter類

Formatter需要向其構造器傳遞一些資訊,以告訴它最終的結果將傳向哪裡

package com.str;

import java.io.*;
import java.util.*;

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 id(%d,%d)\n", name,x,y);
    }

    public static void main(String[] args) {
        PrintStream out = System.out;
        Turtle tommy = new Turtle("tommy",new Formatter(System.out));
        Turtle terry = new Turtle("terry",new Formatter(out));
        tommy.move(0, 0);
        terry.move(4, 8);
        tommy.move(3, 4);
        terry.move(2, 5);
        tommy.move(3, 3);
        terry.move(3, 3);
    }

}

格式化說明符

package com.str;

import java.util.Formatter;

public class Receipt {

    private double total = 10;
    private Formatter f = new Formatter(System.out);

    public void printTitle(){
        f.format("%-15s %5s %10s\n", "Item","Qty","Price");
        f.format("%-15s %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 %10.2f\n", "Tax",4,4.25);
        f.format("%-15s %5s %10s\n", "","","-----");
        f.format("%-15s %5s %10.2f\n", "Total","",total);
    }

    public static void main(String[] args) {
        Receipt receipt = new Receipt();
        receipt.printTitle();
        receipt.print("abc", 1, 4.25);
        receipt.print("def", 2, 4.25);
        receipt.print("ghi", 3, 4.25);
        receipt.printTotal();
    }

}
/*
輸出:
Item              Qty      Price
----              ---      -----
abc                 1       4.25
def                 2       4.25
ghi                 3       4.25
Tax                 4       4.25
                           -----
Total                      22.75
*/

數字代表所佔位數,-號代表左對齊

Formatter轉換

最常用的型別轉換:
d:整數型(十進位制)
c:Unicode字元
b:Boolean值
s:String
f:浮點數(十進位制)
e:浮點數(科學計數)
x:整數(十六進位制)
h:雜湊碼
%: 字元“%”

String.format()

在String.format()內部,也是建立一個Formatter物件,然後呼叫format()。

6,正則表示式

關於正則表示式,不進行介紹了。
看java中是如何實現正則表示式的。
java正則表示式中的“\”與其他語言中的不一樣!

public class IntegerMatch {

    public static void main(String[] args) {
        System.out.println("-1234".matches("-?\\d+"));
        System.out.println("5678".matches("-?\\d+"));
        System.out.println("+911".matches("-?\\d+"));
        System.out.println("+911".matches("(-|\\+)?\\d+"));
    }

}
/*
輸出:
true
true
false
true
*/

java中的“\”與其他語言的“\”是一樣的。
字串型別有matches()方法,返回布林值,引數是一個正則表示式。

String類還有一個正則表示式工具——spliy(),用於將字串從正則表示式的地方切開。

package com.str;

import java.util.Arrays;

public class Splitting {

    public static String knights = "Then-when you have found the";

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

    public static void main(String[] args) {
        split(" ");
        split("\\w+");
        split("n\\w+");
    }

}
/*
輸出:
[Then-when, you, have, found, the]
[, -,  ,  ,  ,  ]
[Then-when you have fou,  the]
*/

\w代表單詞字元。

另一個有用的工具是替換工具。

package com.str;

public class Replacing {

    public static void main(String[] args) {
        String knights = "Then-when you have found the found";
        System.out.println(knights.replaceFirst("f\\w+", "located"));
        System.out.println(knights.replaceAll("f\\w+", "located"));
    }

}
/*
輸出:
Then-when you have located the found
Then-when you have located the located
*/

建立正則表示式

正則表示式的完整構造子列表,參考JDK文件java.util.regex的Pattern類.

字元

B          指定字元B
\xhh       十六進位制值為oxhh的字元
\xhhhh     十六進位制表示為oxhhhh的Unicode字元
\t         製表符tab
\n         換行符
\r         回車
\f         換頁
\e         轉義(Escape)

字元類

[abc]         包含a,b,和c,的任何字元(和a|b|c作用相同)
[^abc]        除了a,b,c,之外的任何字元
[a-zA-Z]      從a到z或從A到Z的任何字元(範圍)
[abc[hij]]    任意a,b,c,h,i,j字元,與a|b|c|h|i|j作用相同
[a-z&&[hij]]  任意h,i,或j(取交集)
\s            空白符(空格,tab,換行,換頁,和回車)
\S            非空白符([^0-9])
\d            數字[0-9]
\D            非數字[^0-9]
\w            詞字元[a-zA-Z0-9]
\W            非詞字元[^\w]

邏輯操作符

XY          Y跟在X後面
X|Y         X或Y
(X)         捕獲組(capturing group)。可以在表示式中用\i引用第i個捕獲組

邊界萬用字元

^            一行的開始
$            一行的結束
\b           詞的邊界
\B           非詞的邊界
\G           前一個匹配結束

如下程式碼示例:

package com.str;

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));
        }
    }

}
/*
輸出:
true
true
true
true
*/

量詞

  • 貪婪性
  • 勉強性
  • 佔有性(java特有的)
    書上沒給示例,不太懂,標記一下

Pattern和matcher

package com.str;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestRegularExpression {

    public static void main(String[] args) {
        Pattern p = Pattern.compile("a(\\w)+");
        Matcher m = p.matcher("aaa abc aqu iop");
        while(m.find()){
            System.out.println(m.group()+" "+m.start()+" "+m.end());
        }
        System.out.println(Pattern.matches("a+", "aaa"));
        String[] s = p.split("aaa,abc.adf");
        for(String ss:s){
            System.out.print(ss+" ");
        }
    }

}
/*
輸出:
aaa 0 3
abc 4 7
aqu 8 11
true
 , . 
*/

Pattern.compile();方法生成一個正則表示式物件,然後用此物件的matcher()方法匹配想要匹配的字串,該方法返回一個Matcher物件。

Matcher物件有佷多方法。
find()方法返回布林值,這個方法會從頭到尾一直匹配,只要匹配到就返回ture,過載的find()還能有一個整數的引數,規定匹配開始的位置,不過後一個find()方法會不斷的回到搜尋的其實位置,而不會往下匹配!
group()方法返回匹配到的字串
start()與end()方法返回所匹配的子串在父串的位置。

另外,Pattern的靜態方法matches()接受一個正則表示式,和一個字串,返回布林值,以此來判斷是否完全匹配。
Pattern物件有split()方法,它接受一個字串,然後把這個字串根據compile()的正則表示式分割成一個字串陣列。

7,掃描輸入

如果不用掃描輸入,那麼從檔案和標準輸入則很麻煩,看如下程式碼:

package com.str;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

public class SimpleRead {

    public static BufferedReader input  = new BufferedReader(
            new StringReader("Sir Robin of Camelot\n22 1.61803"));
    public static void main(String[] args) throws IOException {
        System.out.println("what is your name?");
        String name = input.readLine();
        System.out.println(name);
        System.out.println("double");
        System.out.println("(double)");
        String numbers = input.readLine();
        System.out.println(numbers);
        String[] numArray = numbers.split(" ");
        int age = Integer.parseInt(numArray[0]);
        double favorite = Double.parseDouble(numArray[1]);
        System.out.println(age);
        System.out.println(favorite);
    }

}
/*
輸出:
what is your name?
Sir Robin of Camelot
double
(double)
22 1.61803
22
1.61803
*/

可以看到,需要一行一行的讀取,然後進行擷取,再用Integer,Double的各種解析方法來解析資料。

使用掃描類Scanner則很方便:

package com.str;

import java.util.Scanner;

public class BetterRead {

    public static void main(String[] args) {
        Scanner stdin = new Scanner(SimpleRead.input);
        System.out.println("name");
        String name = stdin.nextLine();
        System.out.println(name);
        System.out.println("double");
        int age = stdin.nextInt();
        double favorite = stdin.nextDouble();
        System.out.println(age);
        System.out.println(favorite);
    }

}

Scanner的構造器可以接受很合型別的輸入物件,包括FILE物件,InputStream,String和Readable。

Scanner界定符

在預設情況下,Scanner根據空白字元對輸入進行分詞,但也可以使用正則表示式指定自己的界定符;

package com.str;

import java.util.Scanner;
import java.util.regex.Pattern;

public class ScannerDelimiter {

    public static void main(String[] args) {
        Scanner scanner = new Scanner("12,42,78,99,42");
        scanner.useDelimiter("\\s*,\\s*");
        Pattern p = scanner.delimiter();
        while(scanner.hasNextInt()){
            System.out.println(scanner.nextInt());
        }
    }

}

useDelimiter()方法規定要使用的界定符,delimiter()返回界定符正則表示式的Pattern物件。

用正則表示式掃描

掃描複雜資料:

package com.str;

import java.util.Scanner;
import java.util.regex.MatchResult;

public class ThreatAnalyzer {

    static String threatDate = 
            "[email protected]/10/2016\n"+
            "[email protected]/10/2016\n"+
            "[abc deg asd asd qwe]";

    public static void main(String[] args) {
        Scanner sc = new Scanner(threatDate);
        String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@"+
                "(\\d{2}/\\d{2}/\\d{4})";
        while(sc.hasNext(pattern)){
            sc.next(pattern);
            MatchResult match = sc.match();
            String ip = match.group(1);
            String date = match.group(2);
            System.out.println("Thread on "+date+" from "+ip);
        }
    }

}
/*
輸出:
Thread on 02/10/2016 from 59.27.82.161
Thread on 01/10/2016 from 59.27.82.161
*/

先分析資料的格式,寫出相應的正則表示式,在使用Scanner物件的next()方法時,把正則表示式當做引數傳入,然後呼叫match()方法就會返回一個MatchResult物件,用該物件操作資料。
在此需要注意的是正則表示式中不要有界定符!

8,StringTokenizer

使用正則表示式和Scanner分隔字串就可以了,這個類已經廢棄不用了!,不用管了。

相關推薦

JAVA程式設計思想學習筆記---十三字串

1,不可變String String物件時不可變的,每一個看起來會修改String的方法,實際上都是建立了一個全新的String物件,而最初的String物件絲毫未動! package com.str; public class Immutable {

Java程式設計思想學習筆記-11

.title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top: 0 } .todo { font-famil

java程式設計思想學習筆記——1 物件導論

1.1 抽象過程 面向物件思想的實質:程式可以通過新增新型別的物件使自身適用於某個特定問題。 面向物件思想的五個基本特徵: 1)萬物皆物件 2)程式是物件的集合 3)每個物件都有自己的由其他物件所構成的儲存 4)每個物件都有其型別 5)某一特定型別的所有物件都可以接收同樣的訊息 物件具有行為、

java程式設計思想學習筆記——2 一切都是物件

儘管java是基於C的,但是相比之下,java是一種更“純粹”的面向物件程式設計語言。 2.1 用引用操縱物件 一切都視為物件,因此可採用單一固定的語法。儘管這一切都看作物件,但操縱的識別符號實際上是物件的一個“引用(reference)”。 java語言的一個特性:字串可以用帶引號的文字初始化。通常,

Java程式設計思想學習筆記——7 複用類

7.8 final關鍵字 final指得是“這是無法改變的”。不想做改變可能出於兩種理由:設計或效率。 可能使用到final的三種情況:資料、方法和類。 7.9初始化及類的載入 載入時眾多變得更加容易的動作之一,因為Java中的所有事物都是物件。請記住,每個類的編譯程

Java程式設計思想學習(三)----操作符

3.2使用Java操作符   操作符接受一個或多個引數,並生成一個新值。   操作符作用於運算元,生成一個新值。有些操作符可以改變運算元自身的值。幾乎所以的操作符都只能操作“基本型別”。例外的操作符有“=”,“==”,“!=”,這些操作符能操作所有物件。String支援“+”和“+=”。  3

Java程式設計思想學習(四)----控制執行流程

  在Java中,涉及的關鍵字包括if-else、while、do-while、for、return、break 以及選擇語句switch。然而,Java並不支援goto語句(該語句引起許多反對意見,但它仍是解決某些特殊問題的最便利的方法)。在Java中,仍然可以進行類似goto那樣的跳轉,但比起典型的got

Java程式設計思想學習(五)----5初始化與清理

隨著計算機革命的發展,“不安全”的程式設計方式已逐漸成為程式設計代價高昂的主因之一。 C++引入了構造囂(constructor)的概念,這是一個在建立物件時被自動呼叫的特殊方法。Java中也採用了構造器,並額外提供了“垃圾回收器”。對於不再使用的記憶體資源,垃圾回收器能自動將其釋放。 5.1 用構造器確

Java程式設計思想讀書筆記——訪問許可權控制

第六章 訪問許可權控制 初學Java的時候很納悶,為什麼要提供各種訪問修飾,都用public不就行了,程式都能執行,還多省事 我感覺如果這個程式只有你自己去編寫,去維護,那麼其實訪問許可權可以忽略 但是,比如說我寫了一個第三方開源庫,有很多很多的人在使用我的庫,那麼如

java程式設計思想讀書筆記---- 內部類

1、建立內部類   將類的定義置於外部類的裡面,在外部類中可以直接new一個內部類的事例,通常外部類會有一個方法,該方法會返回一個指向內部類的引用。如果從外部類非靜態方法之外的位置其它類建立某個內部類的物件,必須具體的指明這個物件的型別:OutClassNam

Java編程思想筆記 十三 字符串

多行 行為 split 字符串數組 lag 一次 regex 方式 lines 1.String對象不可變 String對象不可變,只讀。任何指向它的引用都不能改變它的內容。改變String內容意味著創建了一個新的String對象。 String 對象作為方法參數時都會復

Java編程思想學習筆記-11

none relative gnu script contain ima org reverse equals .title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center

java編程思想學習筆記——2 一切都是對象

機器 發生 基本類型 實現 內存池 默認值 改進 因此 成員方法 盡管java是基於C的,但是相比之下,java是一種更“純粹”的面向對象程序設計語言。 2.1 用引用操縱對象 一切都視為對象,因此可采用單一固定的語法。盡管這一切都看作對象,但操縱的標識符實際上是對象的一個

Java程式設計思想 十三字串

1.不可變String String物件是不可變的,每一個看似修改了String值的方法,實際上都是建立了一個全新的String物件。 public class Immutable { public static String upCase(String s){ return

java程式設計思想讀書筆記 十五 泛型 (匿名內部類和擦除)

1.匿名內部類 泛型還可以應用於內部類以及匿名內部類。下面的例子使用匿名內部類實現了Generator介面: public class Customer { private static long counter = 1; private f

R語言程式設計藝術學習筆記列表

終於又回來寫《R語言程式設計藝術》的學習筆記了,堅持真的很難,戰勝懶惰,堅持把這本書的學習筆記寫完,自我監督!堅持分享之路! 列表這章主要包含列表的建立、增加、刪除和函式應用。 列表也是向量,但是和向量有不同之處,向量中的元素只能是一種型別,但是列表中的元件可以是多種型別。 一、建立列表

JAVA程式設計思想學習筆記(一)

物件導論 1.1 抽象過程 Smalltalk的五個基本特性: 萬物皆為物件。 程式是物件的集合,它通過傳送訊息來告知彼此所要做的。 每個物件都有自己的由其他物件所構成的儲存。 每個物件都有其型別。 某一特定型別的所有物件都可以接受同樣的訊息。

深度學習花書學習筆記 十三 線性因子模型

線性因子模型通常用作其他混合模型的組成模組,用於描述資料生成過程。 各種線性因子模型的主要區別在先驗概率不一樣。概率PCA服從高斯先驗。 獨立成分分析不服從高斯先驗。其功能類似em演算法。用於分離特徵。區別? 慢特徵分析(SFA)源於慢性原則。 稀疏編碼可以進行特徵選擇。 PCA

201711671203《Java程式設計學習報告十三週(完結,暫告一段落)

下週就考Java了,這學期的Java學習報告就到這裡結束了。寒假的時候可能會寫幾篇複習的,或者寫寫自己的程式吧。 教材內容總結 十四、圖形、影象與音訊 元件類Component類有一個方法public void paint(Graphics g),程式可以在其子類中重寫,當程式執行時,J

java程式設計思想學習筆記初始&過載&this&static

構造器初始化 構造器 ,採用與類相同的名稱,建立物件時,自動呼叫構造器來初始化物件 預設構造器(無參構造器):不接受任何引數的構造器 構造器也可帶引數,指定如何建立物件 當類中沒有構造器,編譯器會自動建立一個預設構造器; 當類中已經定義了一個構造