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