115
本本本本 本本本本本本本 本本本本本本本本本本本本本本本本本本本本本本本本本本本 本本本本本 本本本 本本本本本本本本本本本 本本本本 本本本 本本本本本本本 本本 ()(),,、、( 本本本本本本本本本本本本本本本 80% 本本本本本本本本本本本本本本本 本本本本本本本本本本本本本本本本 本本本本本本本本本本本本本本本本本本 本本本本本本本本本 ),,、; 本本本本 本本本本本本本本本本本本本本本本 本本本本本本本本本本本本本本本本本本本本本本本本本本本本 ,,。 本本本本本 © 本本本本本本本本本本 本本 (String) 本 10 本

SCJP ch10

Embed Size (px)

DESCRIPTION

 

Citation preview

本投影片(下稱教用資源)僅授權給採用教用資源相關之旗標書籍為教科書之授課老師(下稱老師)專用,老師為教學使用之目的,得摘錄、編輯、重製教用資源(但使用量不得超過各該教用資源內容之 80% )以製作為輔助教學之教學投影片,並於授課時搭配旗標書籍公開播放,但不得為網際網路公開傳輸之遠距教學、網路教學等之使用;除此之外,老師不得再授權予任何第三人使用,並不得將依此授權所製作之教學投影片之相關著作物移作他用。

著作權所有 © 旗標出版股份有限公司

字串 (String)

第 10 章

2

學習目標

瞭解 String 類別 熟練 String 類別所提供的方法 認識 StringBuffer 與 StringBuilder 類別 使用規則表示法 (Regular Expression)

3

前言

在第 3 章中 , 曾經簡短地介紹過字串這種資料型別 , 而且在前幾章的範例中幾乎也都使用到字串 , 大家應該對於字串都不陌生。

在這一章中 , 我們要針對字串其實是 String 物件這一件事加以說明 , 並且會介紹 String 類別所提供用來處理字串內容的許多方法。

最後 , 還會介紹專責比對字串的規則表示法 (Regular E

xpression), 讓大家可以善用字串。 學會本章介紹的各種 String 類別應用後 , 讀者會發現 ,

不需瞭解 String 類別是如何設計 / 運作 , 我們就能善加利用它 , 相信讀者也更能體會資訊隱藏的妙用。

4

10-1 字串的產生

字串其實就是 String 物件 , 所以宣告一個字串變數 ,

就等於是宣告一個指到 String 物件的參照 , 然後再產生 String 物件。

為了要能正確的產生物件 , 首先來看看 String 類別所定義常用的建構方法。

5

字串的產生

6

字串的產生

其中 StringBuffer 與 StringBuilder 類別會在 10-

3 節中介紹。底下就來看看如何透過前 4 個建構方法產生字串:

7

字串的產生

8

字串的產生

1. 第 6 行使用不需參數的建構方法建構出來的就是空的字串 , 也就是一個內容為 0 個字元的字串。

2. 第 7 行由 test 所指字元陣列建構字串 , 因此建構出的字串內容為 " 這是個測試字串 " 。

3. 第 8 行由 test 所指字元陣列中索引碼為 3 的元素開始 , 取出 4 個元素建構字串。由於陣列元素索引碼是從 0 起算 , 所以建構出來的字串為 " 測試字串 " 。

9

字串的產生

4. 第 9 行由剛剛建立的字串 b 產生副本 , 因此內容一樣。

5. 第 17 行是特別展示 , 讓大家瞭解雖然字串 d 和字串 b 的內容一樣 , 但卻是不同的物件個體 , 所以 == 運算比較參照值的結果並不相等。如果要進行字串內容的比對 , 必須使用稍後會介紹的 equal

s() 方法。

10

10-1-1 Java 對於 String 類別的特別支援

從剛剛的描述可以想見 , 對於像是字串這樣常用的資料型別 , 如果要一一使用建構方法來建立物件其實並不方便 , 因此 , Java 語言對於 String 類別提供了幾個特別的輔助。

11

使用字面常數建立 String 物件 Java 對於 String 類別最重要的支援 , 除了可以用

+ 號來連接字串之外 , 還可以使用字面常數來產生 String 物件 , 例如:

12

使用字面常數建立 String 物件

其中第 4 行就是直接使用字面常數建立物件。當程式中有字面常數時 , Java 編譯器其實會產生一個 St

ring 物件來代表所有相同內容的字面常數字串。 也就是說 , 第 5 行設定給 b 的參照值其實和給 a

的是一樣的 , 都指向同一個 String 物件;而第 6 行傳給 String 類別建構方法的也是同一個物件。

13

使用字面常數建立 String 物件 您可以把這 3 行看成是這樣:

因此 , 第 8 行的 a == b 就會是 true, 因為 a 和 b 指向同一個物件 , 參照值相等。

但是 c 則是建立副本 , 指向另一個新物件 , 所以不論是 a == c 或是 b == c 都不會相同。

如果要比對字串的內容 , 就必須使用 String 類別的equals() 方法。

14

使用字面常數建立 String 物件

15

使用字面常數建立 String 物件

▪ == 運算子與呼叫 equals() 方法的差異也是應考重點 ,

請特別留意。

16

使用字面常數建立 String 物件

對於英文字串 , 則有另一個 equalsIgnoreCase() 方法 , 可在不分大小寫的情況下 , 進行字串比對。

亦即用 equals() 方法比對時 , "ABC" 和 "abc" 會被視為不同;但用 equalsIgnoreCase() 方法 , 則會將 "ABC" 和 "abc" 視為相同 , 例如執行『 "ABC".

equalsIgnoreCase("abc")』會傳回 True 。

17

10-1-2 String 物件的特性

String 類別還有幾個特性 , 是單單從表面無法發掘的 ,

瞭解這些特性對於正確使用字串有很大的幫助。

18

自動轉型 (Implicit Conversion)

搭配連接運算使用時 , 如果連接的運算元中有非 Str

ing 物件 , Java 會嘗試將該運算元轉換為 String 物件 , 轉換的方式就是呼叫該運算元的 toString() 方法 , 例如。

19

自動轉型 (Implicit Conversion)

20

自動轉型 (Implicit Conversion)

要注意的是 , toString() 方法必須傳回 String 物件 ,

而且必須加上 public 存取控制。▪ 若是字串與基本資料型別的變數做連接運算 , 則該變數會被包裝成對應類別的物件 , 再呼叫該類別的 toSt

ring() 方法 , 詳見第 11-4-2 節。

21

String 物件的內容無法更改

String 物件一旦產生之後 , 其內容就無法更改 , 即便是連接運算 , 都是以運算元連接之後的字串產生新的 String 物件作為運算結果。

除此之外 , String 類別所提供的各個方法也都是傳回一個新的字串 , 而不是直接更改字串的內容。

如果需要能夠更改字串內容的物件 , 必須使用 10-3

節會介紹的 StringBuffer 或是 StringBuilder 類別。

22

10-2 String 類別的方法

String 類別提供許多處理字串的方法 , 可以幫助您有效的使用字串 , 我們將在這一節為您介紹一些重要的方法 , 相關資訊可以在 JDK 的說明文件中找到。

要特別再提醒讀者 , 以下傳回值型別為 String 的方法都是『傳回副本』 , 而不會修改原本的字串內容。

23

char charAt(int index)

傳回 int 所指定索引碼的字元 , 字串和陣列一樣 ,

索引碼是從 0 開始算起 , 因此字串中的第 1 個字元的索引碼就是 0 。

24

char charAt(int index)

25

int compareTo(String anotherString)

以逐字元方式 (Lexically) 與 anotherString 所指字串的內容比較 , 如果 anotherString 比較大 , 就傳回一個負數值。

如果字串內容完全相同 , 就傳回 0 ;如果 another

String 比較小 , 就傳回一個正數值。

26

int compareTo(String anotherString)

至於兩個字串 a 與 b 之間的大小 , 是依照以下的規則來決定:1. 由索引 0 開始 , 針對 a 與 b 相同索引碼的字元逐一比較其標準萬國碼 (Unicode), 一旦遇到相同位置但字元不同時 , 就以此位置的字元相比較決定 a 與 b 的順序。例如 , a 為 "abcd" 、 b 為 "abed", 索引碼 0 、 1 這兩個位置的字元皆相同 , 但索引碼 2 的地方 a 為 'c' 、 b 為 'e', 所以 b 比 a 大。

2. 如果 a 與 b 的長度相同 , 且逐一字元比較後 , 同位置的字元皆相同 , 就傳回 0 。此時 , a.equals(b) 或是 b.equals(a) 皆為 true 。

27

int compareTo(String anotherString)

3. 如果 a 與 b 長度不同 , 且逐一字元比較後 , 較短的一方完全和較長的一方前面部分相同 , 就比較 a

與 b 的長度決定大小。例如 , 如果 a 為 "abc" 、b 為 "abcd", 那麼 a 就小於 b 。

4. 在標準萬國碼中 , 英文字母的順序就是字碼的順序 ,

另外 , 大寫字母是排在小寫字母前面 , 所以相同字母時 , 小寫大於大寫。

28

int compareTo(String anotherString)

29

int compareTo(String anotherString)

與 equals() 方法類似 , Compareto() 方法也有一個雙胞胎 compareToIgnoreCase(), 在比較時會將同一字母大小寫視為相同。

30

boolean contains(CharSequence s)

傳回字串中是否包含有 s 所指字串的內容在裡頭。

31

甚麼是 CharSequence 類別 ( 上面方法的參數型別 )

CharSequence 其實並不是類別 , 而是一個介面 (In

terface) 。 我們會在第 12 章介紹介面 , 這裡您只要知道所有出現 CharSequence 型別參數的地方 , 都表示該參數可以是 String 或是 StringBuilder 、 StringBuffer

類別的物件即可。

32

boolean endsWith(String suffix)

傳回是否以指定的字串內容結尾。

33

void getChars(int srcBegin, int srcEnd, char[ ] dst, int dstBegin)

將索引碼 srcBegin 到 srcEnd - 1 的字元 , 複製到 dst 所指字元陣列、由索引碼 dstBegin 開始的元素中。

34

區段的表示法

在 Java 中 , 表示一個區段時 , 都是以開頭元素的索引碼以及結尾元素的下一個元素的索引碼來表示 ,

請熟悉這種表示方法 , 避免弄錯包含的區段。

35

int indexOf(int ch)

傳回 ch 所指定的字元在字串中第一次出現位置的索引碼 , 如果字串中未包含該字元 , 就傳回 -1 。

36

int indexOf(int ch)

這個方法有個雙胞胎的版本 , 叫做 lastIndexOf(),

可以從字串尾端往前尋找。

37

int indexOf(int ch, int fromIndex)

indexOf() 方法的多重定義版本 , 可以透過 fromInd

ex 指定開始尋找的位置。 只要結合這 2 種 indexOf() 方法 , 就可以逐一找出字串中所有出現指定字元的位置了。

這個方法也有個雙胞胎的版本 , 叫做 lastIndexOf(),

可以從字串尾端往前尋找。

38

int indexOf(String str)

indexOf() 的多重定義版本 , 尋找的是指定字串出現的位置。

39

int indexOf(String str)

這個方法也有個雙胞胎的版本 , 叫做 lastIndexOf(),

可以從字串尾端往前尋找。

40

int indexOf(String str, int fromIndex)

indexOf() 方法的多重定義版本 , 可以透過 fromInd

ex 指定開始尋找的位置。 只要結合這 2 種 indexOf() 方法 , 就可以逐一找出所有出現指定字串的位置了。

當然也有個對應的 lastIndexOf() 方法 , 可以從字串尾端往前尋找。

41

int length()

傳回字串的長度。

42

String replace(char oldChar, char newChar)

將字串中所有出現 oldChar 所指定的字元取代為由 newChar 所指定的字元。

要提醒您的是 , 這並不會更改原始字串的內容 , 而是將取代的結果以新的字串傳回。

43

String replace(CharSequence target, CharSequence replacement)

和上一個方法功能類似 , 但是將字串中所有出現 tar

get 所指字串內容的地方都取代為 replacement 所指字串的內容。

44

boolean startsWith(String prefix)boolean startsWith(String prefix, int offset)

startsWith() 的用法和前面看過的 endsWith() 類似 ,

但功能相反 , startsWith() 是用來檢查目前字串是否是以參數字串 prefix 開頭。

較特別的是 startsWith() 有兩個參數的版本 , 可指定從索引位置 offset 開始 , 檢查是否以參數字串 p

refix 為開頭。

45

boolean startsWith(String prefix)boolean startsWith(String prefix, int offset)

46

String substring(int beginIndex)

傳回由 beginIndex 所指定索引開始到結尾的子字串。

47

String substring(int beginIndex, int endIndex)

傳回由 beginIndex 所指定的索引碼開始到 endIndex - 1 所指定的索引碼為止的部分字串。

48

String toLowerCase()

傳回將字串中的字元轉成小寫後的副本。

49

String toUpperCase()

將字串中的字元全部轉為大寫。

50

String trim()

將字串中頭、尾端的空白符號去除,包含空白字元、定位字元等等。

51

String trim()

▪ 以上這些方法都經常會用到 , 也是應考的重點。

52

10-3 StringBuffer 與 StringBuilder 類別

前 2 節我們一直強調 , String 物件無法更改其字串內容 , 這主要是因為如此一來 , String 物件就不需要因為字串內容變長或是變短時 , 必須進行重新配置儲存空間的動作。

但如果您必須使用可以隨時更改內容的字串 , 那麼就必須改用 StringBuffer 或是 StringBuilder 類別。

53

10-3-1 StringBuffer 類別

基本上 , 我們可以把 StringBuffer 類別看成是『可改變內容的 String 類別』。

因此 StringBuffer 類別提供了各種可改變字串內容的方法 , 像是可新增內容到字串中的 append() 及 insert() 、可刪除字串內容的 delete() 。

以下先來看 StringBuffer 類別的建構方法:

54

StringBuffer 類別

55

StringBuffer 類別

還記得在 10-5 頁提過 , Java 會產生一個 String

物件來代替程式中的字面常數 , 所以第 4 、 5 行也可直接寫成:

以下就來介紹 StringBuffer 類別的修改字串方法 ,

這些方法不但會直接修改 StringBuffer 物件的內容 ,

也會將修改後的結果傳回。

56

append() 方法

StringBuffer 物件並不能使用 "+" 運算子來連接字串 , 而必須使用 append() 或是 insert() 方法。

append() 方法會在字串尾端添加資料 , 並且擁有多重定義的版本 , 可以傳入基本型別、 String 物件以及其他有定義 toString() 方法的物件。

它會將傳入的參數轉成字串 , 添加到目前字串的尾端 ,

然後傳回自己。

57

append() 方法

58

insert() 方法

insert() 方法和 append() 方法一樣有多種版本 , 但是它可以透過第 1 個參數 offset 將第 2 個參數插入到字串中的特定位置。

offset 代表的是索引碼 , insert() 方法會把資料插入到 offset 所指的位置之前。

59

insert() 方法

在第 11 行可以看到 , 如果第 1 個參數傳入字串的長度 , 就等於是 append() 了。

60

StringBuffer delete(int start, int end)

delete() 方法可以刪除由 start 所指定索引碼開始到 end - 1 所指定索引碼之間的一段字元。

61

StringBuffer deleteCharAt(int index)

刪除由 index 所指定索引碼的字元。

62

StringBuffer replace(int start, int end, String str)

將 start 所指定索引碼開始到 end - 1 所指定索引碼之間的一段字元取代為 str 所指定的字串。

63

StringBuffer reverse()

將整個字串的內容頭尾反轉。例如:

64

void setCharAt(int index, char ch)

將 index 所指定索引碼的字元取代成 ch 所指定的字元。

請特別注意 , 這是唯一一個更改了字串內容 , 但卻沒有傳回自己的方法 , 在使用時要特別小心。

65

void setCharAt(int index, char ch)

66

其他方法

StringBuffer 也提供下列方法 , 其用法和 String 類別的同名方法相同 (請注意 , 這些方法都不會更改到物件本身的內容 , 也不會傳回 StringBuffer 物件 ) :▪ char charAt (int index)

▪ void getChars (int srcBegin, int srcEnd, char[ ] dst, int

dstBegin)

▪ int indexOf (String str)

▪ int indexOf (String str, int fromIndex)

67

其他方法

▪ int lastIndexOf (String str)

▪ int lastIndexOf (String str, int fromIndex)

▪ int length ()

▪ String substring (int start)

▪ String substring (int start, int end)

68

10-3-2 StringBuilder 類別

這個類別和 StringBuffer 的用途相同 , 且提供的方法一模一樣 , 唯一的差別就是此類別並不保證在多執行緒的環境下可以正常運作 , 有關多執行緒 , 請參考第 15 章。

如果您使用字串的場合不會有多個執行緒共同存取同一字串的話 , 建議可以改用 StringBuilder 類別 , 以得到較高的效率。

如果會有多個執行緒共同存取字串的內容 , 就必須改用 StringBuffer 類別。

69

10-4 規則表示法 (Regular Expression)

在字串的使用上 , 有一種用途是接收使用者鍵入的資料 , 比如說身份證字號、電話號碼、或者是電子郵件帳號等等。

為了確保後續的處理正確 , 通常都會希望使用者依據特定的格式輸入 , 以避免使用者輸入不合乎該項資料的字元。

因此 , 在這類應用中 , 一旦取得使用者輸入的資料 ,

第一件事就是要判斷使用者是否依據規定的格式輸入 ,

然後才進行後續的處理。

70

規則表示法 (Regular Expression)

在 String 類別中 , 雖然已經提供有多個方法可以讓您比對字串的內容 , 可是要比對字串內容是否符合特定的格式 , 例如 02-28833498 這種電話號或是 joh

[email protected] 這樣的電子郵件信箱等等具有規則的樣式 , 使用起來並不方便。

因此我們需要一種可以描述字串內容規則的方式 , 然後依據此一規則來驗證字串的內容是否相符。

String 類別的 matches() 方法 , 就可以搭配規則表示法來解決這樣的問題。

71

10-4-1 甚麼是規則表示法

讓我們先以一個最簡單的範例來說明甚麼是規則表示法。

假設程式需要使用者輸入一個整數 , 那麼當取得使用者輸入的資料後 , 就必須檢查使用者所輸入的是否為整數。

要完成這件事 , 最簡單、直覺的方法就是使用一個迴圈 , 一一取出字串中的各個字元 , 檢查這個字元是否為數字。

72

甚麼是規則表示法

73

甚麼是規則表示法

74

甚麼是規則表示法

第 16 行的 for 迴圈就是從 str 所指字串中一一取出個別字元 , 並比對是否為數字 , 並且在使用者的輸入資料包含有非數字時顯示錯誤訊息。

75

比對數字

由於在標準萬國碼中 , 數字 '0' 、 ' 1' 、 '

2' 、 ..... 、 ' 9' 的字碼是連續的 , 因此只要比對字元是否位於 '0' 到 '9' 之間 , 即可確認該字元是否為數字。

76

甚麼是規則表示法

如果把第 16 行的迴圈用簡單的一句話來說 , 就是要檢查使用者所輸入的資料是否都是數字。

如果改用 String 類別的 matches() 方法搭配規則表示法 , 就可以更清楚的表達出比對的規則 , 底下就來修改前面程式的 do 迴圈。

77

甚麼是規則表示法

78

甚麼是規則表示法

第 16 行就是使用 String 類別的 matches() 方法來檢查字串是否符合某種樣式 , 而 "[0- 9] +" 就是用來描述字串樣式的規則。 "[0-9]" 是指數字 0 ~ 9 之間的任意一個字元 , 而後面的 "+" 則是指前面規則所描述的樣式 ( 此例就是 [0-9]) 出現一次以上 , 所以整體來說 ,

這個規則就是『由一或多個數字所構成的字串』。 當字串本身符合所描述的樣式時 , matches() 就傳回 tr

ue, 否則傳回 false 。 因此 , 這個程式就和剛剛使用 for 迴圈檢查的功用一模一樣。

79

甚麼是規則表示法

從這裡您可以看到 , 使用 matches() 方法的好處是可以專注於要比對的樣式 , 至於如何比對 , 就交給 matches() 方法 , 而不需要自己撰寫程式進行。

因此 , 如果您需要比對的是這類可以規則化的樣式 ,

建議多多利用 matches() 方法。

80

10-4-2 規則表示法入門

為了讓大家可以直接練習 , 所以我們先撰寫了一個測試的程式 , 可以讓您直接輸入樣式以及要比對的字串 ,

並顯示出比對的結果是否相符:

81

規則表示法入門

82

規則表示法入門

這個程式會要求使用者輸入比對的樣式以及字串 , 並顯示比對結果。

後續的說明都會以此程式作為測試 , 並顯示執行結果。

83

直接比對字串內容

最簡單的規則表示法就是直接表示出字串的明確內容 ,

比如說如果要比對字串的內容是否為 "print", 那麼就可以使用 "print" 作為比對的樣式:

84

限制出現次數

除了剛剛使用過的 "+" 以外 , 規則表示法中還可以使用如下常用的次數限制規則 ( 量詞 ) :

85

限制出現次數

由於樣式是 "ab?a", 也就是先出現一個 'a', 再出現最多一個 'b', 再接著一個 'a', 所以 "aa" 或是 "ab

a" 都相符 , 但是 "abba" 中間出現了 2 個 'b ', 所以不相符。

86

字元種類 (Character Classes)

您也可以用中括號來表示一組字元 , 比如說:

其中樣式 [bjl] 表示此位置可以出現 'b' 或 'j' 或 'l', 因此 "a[bjl]a" 這個樣式的意思就是先出現一個 'a', 再出現一個 'b' 或 'j' 或 'l ', 再接著一個 'a' 。

在第 2 個執行結果中 , 因為輸入的字串第 2 個字元並非 'b' 或 'j' 或 'l', 所以不相符。

87

字元種類 (Character Classes)

您也可以在中括號中使用 "-" 表示一段連續的字碼區間 , 比如說上一小節使用過的 [0-9] 就包含了數字 , 而 [a-z] 則包含了小寫的英文字母 , [A-Z] 則包含了大寫的英文字母 , [a-zA-Z] 就是所有的英文字母了:

88

字元種類 (Character Classes)

這個範例的樣式表示先出現一個 ' a ' , 然後接著數字或是英文字母 , 再接著一個 'a', 所以第 2 個執行結果因為有 '#' 而不相符。

另外 , 您也可以在左中括號後面跟著一個 '^' , 排除中括號中的字元 , 例如:

89

字元種類 (Character Classes)

這個樣式表示第 2 個字元不能是小寫英文字母 , 所以第 1 個執行結果因為第 2 個字元是 'd' 而不相符。

90

預先定義的字元種類 (Character Class)

由於數字或是英文字母之類的規則很常會用到 ,

因此規則表示法中預先定義了一些字元種類 ,

如右所示:

▪ 由於句號代表任意字元 ,

原來的句號則需以 \.

表示。

91

預先定義的字元種類 (Character Class)

第 2 個執行結果因為第 2 個字元 'b' 不是數字而不相符。

92

群組 (Grouping)

您也可以使用括號將一段規則組合起來 , 搭配限制次數使用 , 例如:

93

群組 (Grouping)

其中以括號將 "c\dc" 組成群組 , 因此整個規則描述的樣式就是先出現一個 'a', 再出現 2 次 "c\dc",

再出現一個 'a' 。 第 1 個執行結果中的 "c1c" 以及 "c2c" 都符合 "c\dc" 樣式 , 而第 2 個執行結果只有 "c1c" 符合 "c\dc" 樣式 , 等於 "c\dc" 僅出現 1 次 , 所以比對不相符。

94

以字面常數指定樣式

如果要在程式中以字面常數指定樣式 , 由於 Java

的編譯器會將 '\' 視為跳脫序列的啟始字元 ( 例如 \

t 表定位字元、 \n 表換行字元、 \\ 代表 \ 字元 ),

因此要使用預先定義的字元種類時 , 就必須在前面多加一個 '\', 以便讓 Java 編譯器將 '\' 視為一般的字元 , 例如:

95

如果寫成這樣:

編譯時就會認為 '\d' 是一個不合法的跳脫序列。

以字面常數指定樣式

96

10-4-3 replaceAll ( ) 方法 規則表示法除了可以用來比對字串以外 , 也可以用來將字串中符合指定樣式的一段文字取代成另外一段文字 , 讓您可以極富彈性的方式進行字串的取代 , 而不是僅能使用簡單的 replace() 方法。

為了簡化 , 我們將剛剛的 RegExTest.java 修改 , 以方便測試 replaceAll() 方法:

97

replaceAll ( ) 方法

98

replaceAll ( ) 方法

這個程式會要求使者輸入原始的字串、要搜尋的樣式、以及要將搜尋到的字串片段取代成甚麼內容 , 最後顯示取代後的結果。

接下來的內容就以這個程式來測試。

99

簡單取代

replaceAll() 最簡單的用法就是當成 replace() 方法使用 , 以明確的字串內容當成樣式 , 並進行取代:

因為搜尋的樣式是 "111", 所以取代的結果就是將字串中的 "111" 取代掉。

100

使用樣式進行取代

replaceAll() 最大的用處是可以使用規則表示法 , 例如:

這裡搜尋的樣式是 "\d+", 所以字串中的 "111" 以及 "34" 都符合這個樣式 , 都會被取代為 " 數字 " 。

101

使用群組 有時候我們會希望取代的結果要包含原來被取代的那段文字 , 這時就可以使用群組的功能 , 例如:

其中要取代成 " 數字 $1" 中的 "$1" 的意思就是指比對相符的那段文字中 , 和樣式中第 1 個群組相符的部分。以本例來說 , 當 "111" 與 "(\d+)" 比對相符時 , 第一個群組就是 "(\d+)", 與這個群組相符的就是 "111" 這段文字 , 所以取代後的結果變成 " 數字 111" ;相同的道理 , 後面比對出 "34" 時 , 就取代為 " 數字 34" 了。

102

使用群組

依此類推 , $2 、 $3 、 ...自然是指第 2 、 3 、 .... 個群組了 , 至於 $0 則是指比對出的整段文字 , 例如:

規則表示法的功能非常強大 , 詳細的說明可以參考 JDK 的說明文件。

103

10-4-4 split( ) 方法

split() 方法可依照特定字元來切割字串 , 並將切割的結果存入字元陣列中傳回。

例如:『 "Ken,Sue,Tom".split(",")』就會以逗號來切割 , 然後傳回 {"Ken","Sue","Tom" } 陣列。

split() 有二種呼叫方法:

104

split( ) 方法

regex 代表一個規則表示法的樣式 , 而 limit 若為正數 , 則表示最多可切割的元素數目。

例如 『 "Ken,Sue,Tom".split(",", 2)』 會傳回只有 2 個元素的 {"Ken","Sue,Tom" } 陣列 , 也就是只會切割一次。

若 limit 為負數 , 即表示不限切割的數目。 若為 0, 則同樣不限切割的數目 , 而且最後面若有空字串的元素 , 也會自動移除;在呼叫 split() 時若省略第二個參數 , 則 limit 預設也是 0 。

105

split( ) 方法

106

split( ) 方法

107

10-A 檢查身份證字號的格式 10-B 檢核身份證字號

108

1. Given:

What is the result?

A. x1,y23,z4, B. x,y,z, C. x,y,,z,

D. x,y,,z,, E. Compilation fails.

109

2. Given :

What is the result? A. x1,y23,z4, B. x,y,z, C. x,y,,z, D. x,y,,z,, E. Compilation fails..

110

3. Given :

Which codes, inserted at line 4, will print "love!"? (Choose all that apply.)A. b.delete(0, 2).replace(1,3,"o").append("!");

B. b.substring(2,6).insert(1, "o").replace(2,6,"ve!");

C. b.delete(6,7).delete(0,2).insert(1, "o").replace(2,6,"ve!");

D. b.insert(3, "o").replace(0,2,"").delete(2,4).replace(3,4,"e!");

E. b = "ove".insert(0,1,"l").append("!");

111

112

4. What 's the result of following program:

A. unm B. udm C. ude

D. Compilation fails. E. Runtime error.

113

5. Given:

Which statements are true? (Choose a l l that apply. )A. This code will have better performance if rewrited to: return

"<"+s.subString(0, n)+">";

B. This code will have better performance if replace StringBuffer to StringBuilder.

C. If replace StringBuffer to StringBuilder, no other change should be made.

D. This code is not thread-safe.

E. This code will be thread-unsafe if replace StringBuffer to StringBuilder.

114

115

6. Which statements concerning String, StringBuffer, and StringBuilder are true? (Choose all that apply.)A. All three classes have a substring() method.

B. All three classes have a length() method.

C. All three classes have overload append() method.

D. Only String class can use + operator.

E. Only StringBuffer class is thread-safe.

F. StringBuilder has better performance than StringBuffer.

G. The value of an object of those classes can be modified by their methods