JAVA數(shù)據(jù)處理
字符串處理
一般程序需要處理大量文本數(shù)據(jù)淮蜈,Java 語言的文本數(shù)據(jù)被保存為字符或字符串類型。字符串是 Java 程序中經(jīng)常處理的對象之一奥此,字符及字符串的操作主要用到 String 類和 StringBuffer 類弧哎,如連接、修改稚虎、替換撤嫩、比較和查找等。
Java定義字符串
字符串是 Java 中特殊的類蠢终,使用方法像一般的基本數(shù)據(jù)類型序攘,被廣泛應(yīng)用在 Java 編程中茴她。Java 沒有內(nèi)置的字符串類型,而是在標準 Java 類庫中提供了一個 String 類來創(chuàng)建和操作字符串程奠。
在 Java 中定義一個字符串最簡單的方法是用雙引號把它包圍起來丈牢。這種用雙引號括起來的一串字符實際上都是 String 對象,如字符串“Hello”在編譯后即成為 String 對象梦染。因此也可以通過創(chuàng)建 String 類的實例來定義字符串赡麦。
不論使用哪種形式創(chuàng)建字符串朴皆,字符串對象一旦被創(chuàng)建帕识,其值是不能改變的,但可以使用其他變量重新賦值的方式進行更改遂铡。
直接定義字符串
直接定義字符串是指使用雙引號表示字符串中的內(nèi)容肮疗,具體方法是用字符串常量直接初始化一個 String 對象,示例如下:
String str = "Hello Java";
或者
String str;str = "Hello Java";
注意:字符串變量必須經(jīng)過初始化才能使用扒接。
使用 String 類定義
前面提到在 Java 中每個雙引號定義的字符串都是一個 String 類的對象伪货。因此,可以通過使用 String 類的構(gòu)造方法來創(chuàng)建字符串钾怔,該類位于 java.lang 包中碱呼。
String 類的構(gòu)造方法有多種重載形式,每種形式都可以定義字符串宗侦。下面介紹最常用的幾種形式愚臀。
注意:具有和類名相同的名稱,而且沒有返回類型的方法稱為構(gòu)造方法矾利。重載是指在一個類中定義多個同名的方法姑裂,但要求每個方法具有不同的參數(shù)的類型或參數(shù)的個數(shù)。
1. String()
初始化一個新創(chuàng)建的 String 對象男旗,表示一個空字符序列舶斧。
2. String(String original)
初始化一個新創(chuàng)建的 String 對象,使其表示一個與參數(shù)相同的字符序列察皇。換句話說茴厉,新創(chuàng)建的字符串是該參數(shù)字符串的副本。例如:
String str1 = new String("Hello Java");
String str2 = new String(str1);
這里 str1 和 str2 的值是相等的什荣。
3. String(char[ ]value)
分配一個新的字符串矾缓,將參數(shù)中的字符數(shù)組元素全部變?yōu)樽址T撟址麛?shù)組的內(nèi)容已被復(fù)制溃睹,后續(xù)對字符數(shù)組的修改不會影響新創(chuàng)建的字符串而账。例如:
char a[] = {'H','e','l','l','0'};
String sChar = new String(a);a[1] = 's';
上述 sChar 變量的值是字符串“Hello”。 即使在創(chuàng)建字符串之后因篇,對 a 數(shù)組中的第 2 個元素進行了修改泞辐,但未影響 sChar 的值笔横。
4. String(char[] value,int offset,int count)
分配一個新的 String,它包含來自該字符數(shù)組參數(shù)一個子數(shù)組的字符咐吼。offset 參數(shù)是子數(shù)組第一個字符的索引吹缔,count 參數(shù)指定子數(shù)組的長度。該子數(shù)組的內(nèi)容已被賦值锯茄,后續(xù)對字符數(shù)組的修改不會影響新創(chuàng)建的字符串厢塘。例如:
char a[]={'H','e','l','l','o'};
String sChar=new String(a,1,4);a[1]='s';
上述 sChar 變量的值是字符串“ello”。該構(gòu)造方法使用字符數(shù)組中的部分連續(xù)元素來創(chuàng)建字符串對象肌幽。offset 參數(shù)指定起始索引值晚碾,count 指定截取元素的個數(shù)。創(chuàng)建字符串對象后喂急,即使在后面修改了 a 數(shù)組中第 2 個元素的值格嘁,對 sChar 的值也沒有任何影響
String&int相互轉(zhuǎn)換
String 在編程中被廣泛使用,所以掌握 String 和 int 的相互轉(zhuǎn)換方法是極其重要的廊移。
String轉(zhuǎn)換為int
String 字符串轉(zhuǎn)整型 int 有以下兩種方式:
- Integer.parseInt(str)
- Integer.valueOf(str).intValue()
注意:Integer 是一個類糕簿,是 int 基本數(shù)據(jù)類型的封裝類。
在 String 轉(zhuǎn)換 int 時狡孔,String 的值一定是整數(shù)懂诗,否則會報數(shù)字轉(zhuǎn)換異常(java.lang.NumberFormatException)逼侦。
int轉(zhuǎn)換為String
整型 int 轉(zhuǎn) String 字符串類型有以下 3 種方法:
- String s = String.valueOf(i);
- String s = Integer.toString(i);
- String s = "" + i;
在使用 valueOf() 方法時孵睬,注意 valueOf 括號中的值不能為空,否則會報空指針異常(NullPointerException)嘉蕾。
valueOf() 荚醒、parse()和toString()
valueOf()
valueOf() 方法將數(shù)據(jù)的內(nèi)部格式轉(zhuǎn)換為可讀的形式芋类。它是一種靜態(tài)方法,對于所有 Java 內(nèi)置的類型界阁,在字符串內(nèi)被重載侯繁,以便每一種類型都能被轉(zhuǎn)換成字符串。valueOf() 方法還被類型 Object 重載泡躯,所以創(chuàng)建的任何形式類的對象也可被用作一個參數(shù)贮竟。這里是它的幾種形式:
static String valueOf(double num)
static String valueOf(long num)
static String valueOf(Object ob)
static String valueOf(char chars[])
與前面的討論一樣,調(diào)用 valueOf() 方法可以得到其他類型數(shù)據(jù)的字符串形式较剃。
例如在進行連接操作時咕别。對各種數(shù)據(jù)類型,可以直接調(diào)用這種方法得到合理的字符串形式写穴。所有的簡單類型數(shù)據(jù)轉(zhuǎn)換成相應(yīng)于它們的普通字符串形式惰拱。任何傳遞給 valueOf() 方法的對象都將返回對象的 toString() 方法調(diào)用的結(jié)果。事實上啊送,也可以通過直接調(diào)用 toString() 方法而得到相同的結(jié)果偿短。
對大多數(shù)數(shù)組欣孤,valueOf() 方法返回一個相當晦澀的字符串,這說明它是一個某種類型的數(shù)組昔逗。然而對于字符數(shù)組降传,它創(chuàng)建一個包含了字符數(shù)組中的字符的字符串對象。valueOf() 方法有一種特定形式允許指定字符數(shù)組的一個子集勾怒。
它具有如下的一般形式:
static String valueOf(char chars[ ], int startIndex, int numChars)
這里 chars 是存放字符的數(shù)組婆排,startIndex 是字符數(shù)組中期望得到的子字符串的首字符下標,numChars 指定子字符串的長度笔链。
parse()
parseXxx(String) 這種形式段只,是指把字符串轉(zhuǎn)換為數(shù)值型,其中 Xxx 對應(yīng)不同的數(shù)據(jù)類型卡乾,然后轉(zhuǎn)換為 Xxx 指定的類型翼悴,如 int 型和 float 型。
toString()
toString() 可以把一個引用類型轉(zhuǎn)換為 String 字符串類型幔妨,是 sun 公司開發(fā) Java 的時候為了方便所有類的字符串操作而特意加入的一個方法。
字符串的拼接
對于已經(jīng)定義的字符串谍椅,可以對其進行各種操作误堡。連接多個字符串是字符串操作中最簡單的一種。通過字符串連接雏吭,可以將兩個或多個字符串锁施、字符、整數(shù)和浮點數(shù)等類型的數(shù)據(jù)連成一個更大的字符串杖们。
String 字符串雖然是不可變字符串悉抵,但也可以進行拼接只是會產(chǎn)生一個新的對象。String 字符串拼接可以使用“+”運算符或 String 的 concat(String str) 方法摘完。“+”運算符優(yōu)勢是可以連接任何類型數(shù)據(jù)拼接成為字符串姥饰,而 concat 方法只能拼接 String 類型字符串。
使用連接運算符“+”
與絕大多數(shù)的程序設(shè)計語言一樣孝治,Java 語言允許使用“+”號連接(拼接)兩個字符串列粪。“+”運算符是最簡單谈飒、最快捷岂座,也是使用最多的字符串連接方式。在使用“+”運算符連接字符串和 int 型(或 double 型)數(shù)據(jù)時杭措,“+”將 int(或 double)型數(shù)據(jù)自動轉(zhuǎn)換成 String 類型费什。
使用 concat() 方法
在 Java 中,String 類的 concat() 方法實現(xiàn)了將一個字符串連接到另一個字符串的后面手素。concat() 方法語法格式如下:
字符串 1.concat(字符串 2);
執(zhí)行結(jié)果是字符串 2 被連接到字符串 1 后面鸳址,形成新的字符串赘那。
如 concat() 方法的語法所示,concat() 方法一次只能連接兩個字符串氯质,如果需要連接多個字符串募舟,需要調(diào)用多次 concat() 方法。
連接其他類型數(shù)據(jù)
前面介紹的例子都是字符串與字符串進行連接闻察,其實字符串也可同其他基本數(shù)據(jù)類型進行連接拱礁。
如果將字符串同這些數(shù)據(jù)類型數(shù)據(jù)進行連接,此時會將這些數(shù)據(jù)直接轉(zhuǎn)換成字符串辕漂。
編寫一個 Java 程序呢灶,實現(xiàn)將字符串與整型、浮點型變量相連并輸出結(jié)果钉嘹。實現(xiàn)代碼如下:
public static void main(String[] args) {
String book = "三國演義"; // 字符串
int price = 59; // 整型變量
float readtime = 2.5f; // 浮點型變量
System.out.println("我買了一本圖書鸯乃,名字是:" + book + "\n價格是:" + price + "\n我每天閱讀" + readtime + "小時");
}
上述代碼實現(xiàn)的是將字符串變量 book 與整型變量 price 和浮點型變量 readtime 相連后將結(jié)果輸出。在這里定義的 price 和 readtime 都不是字符串跋涣,當它們與字符串相連時會自動調(diào)用自身的 toString() 方法將其轉(zhuǎn)換成字符串形式缨睡,然后再參與連接運算。因此陈辱,程序運行后的結(jié)果如下所示:
我買了一本圖書奖年,名字是:三國演義
價格是:59
我每天閱讀2.5小時
假設(shè)將本例中的輸出語句修改為如下形式:
System.out.println("我買了一本圖書,名字是:"+book+"\n 價格是:"+price+"\n我每天閱讀"+(price+readtime)+"小時");
因為運算符具有優(yōu)先級沛贪,而圓括號的優(yōu)先級最高陋守,所以先計算 price 與 readtime 的和,再將結(jié)果轉(zhuǎn)換成字符串進行連接利赋。此時的運行結(jié)果如下所示:
我買了一本圖書水评,名字是:三國演義
價格是:59
我每天閱讀61.5小時
注意:只要“+”運算符的一個操作數(shù)是字符串,編譯器就會將另一個操作數(shù)轉(zhuǎn)換成字符串形式媚送,所以應(yīng)該謹慎地將其他數(shù)據(jù)類型與字符串相連中燥,以免出現(xiàn)意想不到的結(jié)果。
常用的字符串處理方法
字符串獲取長度
在 Java中季希,要獲取字符串的長度褪那,可以使用 String 類的 length() 方法,其語法形式如下:
字符串名.length();
如:在學生信息管理系統(tǒng)中對管理員密碼有這樣的規(guī)定式塌,即密碼長度必須大于 6 位且小于 12 位博敬。因為密碼太短容易被破解,太長的話又不容易記住峰尝。這就需要首先獲取用戶輸入的密碼字符串偏窝,然后調(diào)用 length() 方法獲取長度,再做進一步的長度判斷,最終實現(xiàn)代碼如下所示:
public static void main(String[] args) {
String sys = "學生信息管理";// 字義一個字符串表示系統(tǒng)名稱
System.out.println("歡迎進入《" + sys + "》系統(tǒng)");// 輸出系統(tǒng)名稱
System.out.println("請設(shè)置一個管理員密碼:");
Scanner input = new Scanner(System.in);
String pass = input.next();// 獲取用戶輸入的密碼
int length = pass.length();// 獲取密碼的長度
if (length > 6 && length < 12) {
System.out.println("密碼長度符合規(guī)定祭往。");
System.out.println("已生效伦意,請牢記密碼:" + pass);
} else if (length >= 12) {
System.out.println("密碼過長。");
} else {
System.out.println("密碼過短硼补。");
}
}
上述代碼將用戶輸入的密碼保存到字符串變量 pass 中驮肉,再調(diào)用 pass.length() 方法將長度保存到 length 變量,然后使用 if 語句根據(jù)長度給出提示已骇。
字符串轉(zhuǎn)小寫
String 類的 toLowerCase() 方法可以將字符串中的所有字符全部轉(zhuǎn)換成小寫离钝,而非字母的字符不受影響。語法格式如下:
字符串名.toLowerCase() // 將字符串中的字母全部轉(zhuǎn)換為小寫褪储,非字母不受影響
例如:
String str="abcdef 我 ghijklmn";
System.out.println(str.toLowerCase()); // 輸出:abcdef 我 ghijklmn
字符串轉(zhuǎn)大寫
String 類的toUpperCase() 則將字符串中的所有字符全部轉(zhuǎn)換成大寫卵渴,而非字母的字符不受影響。語法格式如下:
字符串名.toUpperCase() // 將字符串中的字母全部轉(zhuǎn)換為大寫鲤竹,非字母不受影響
例如:
String str="abcdef 我 ghijklmn";
System.out.println(str.toUpperCase()); // 輸出:ABCDEF 我 GHIJKLMN
字符串去空格
字符串中存在的首尾空格一般情況下都沒有任何意義浪读,如字符串“ Hello ”,但是這些空格會影響到字符串的操作辛藻,如連接字符串或比較字符串等碘橘,所以應(yīng)該去掉字符串中的首尾空格,這需要使用 String 類提供的 trim() 方法揩尸。
trim() 方法的語法形式如下:
字符串名.trim()
使用 trim() 方法的示例如下:
String str = " hello ";System.out.println(str.length()); // 輸出 7System.out.println(str.trim().length()); // 輸出 5
從該示例中可以看出蛹屿,字符串中的每個空格占一個位置,直接影響了計算字符串的長度岩榆。
如果不確定要操作的字符串首尾是否有空格,最好在操作之前調(diào)用該字符串的 trim() 方法去除首尾空格坟瓢,然后再對其進行操作勇边。
注意:trim() 只能去掉字符串中前后的半角空格(英文空格),而無法去掉全角空格(中文空格)折联×0可用以下代碼將全角空格替換為半角空格再進行操作,其中替換是 String 類的 replace() 方法诚镰。
str = str.replace((char) 12288, ' '); // 將中文空格替換為英文空格
str = str.trim();
其中奕坟,12288 是中文全角空格的 unicode 編碼。
字符串截取
在 String 中提供了兩個截取字符串的方法清笨,一個是從指定位置截取到字符串結(jié)尾月杉,另一個是截取指定范圍的內(nèi)容。下面對這兩種方法分別進行介紹抠艾。
substring(int beginIndex) 形式
此方式用于提取從索引位置開始至結(jié)尾處的字符串部分苛萎。調(diào)用時,括號中是需要提取字符串的開始位置,方法的返回值是提取的字符串腌歉。例如:
String str = "我愛 Java 編程";
String result = str.substring(3);
System.out.println(result); // 輸出:Java 編程
substring(int beginIndex蛙酪,int endIndex) 形式
此方法中的 beginIndex 表示截取的起始索引,截取的字符串中包括起始索引對應(yīng)的字符翘盖;endIndex 表示結(jié)束索引桂塞,截取的字符串中不包括結(jié)束索引對應(yīng)的字符,如果不指定 endIndex馍驯,則表示截取到目標字符串末尾阁危。該方法用于提取位置 beginIndex 和位置 endIndex 位置之間的字符串部分。
這里需要特別注意的是泥彤, 對于開始位置 beginIndex欲芹, Java 是基于字符串的首字符索引為 0 處理的,但是對于結(jié)束位置 endIndex吟吝,Java 是基于字符串的首字符索引為 1 來處理的菱父,如圖所示。
注意:substring() 方法是按字符截取剑逃,而不是按字節(jié)截取浙宜。
例:創(chuàng)建一個字符串,對它使用 substring() 方法進行截取并輸出結(jié)果蛹磺。示例代碼如下:
public static void main(String[] args) {
String day = "Today is Monday"; //原始字符串
System.out.println("substring(0)結(jié)果:"+day.substring(0));
System.out.println("substring(2)結(jié)果:"+day.substring(2));
System.out.println("substring(10)結(jié)果:"+day.substring(10));
System.out.println("substring(2,10)結(jié)果:"+day.substring(2,10));
System.out.println("substring(0,5)結(jié)果:"+day.substring(0,5));
}
輸出結(jié)果如下所示:
substring(0)結(jié)果:Today is Monday
substring(2)結(jié)果:day is Monday
substring(10)結(jié)果:onday
substring(2,10)結(jié)果:day is M
substring(0,5)結(jié)果:Today
分割字符串
String 類的 split() 方法可以按指定的分割符對目標字符串進行分割粟瞬,分割后的內(nèi)容存放在字符串數(shù)組中。該方法主要有如下兩種重載形式:
str.split(String sign)str.split(String sign,int limit)
其中它們的含義如下:
- str 為需要分割的目標字符串萤捆。
- sign 為指定的分割符裙品,可以是任意字符串。
- limit 表示分割后生成的字符串的限制個數(shù)俗或,如果不指定市怎,則表示不限制,直到將整個目標字符串完全分割為止辛慰。
使用分隔符注意如下:
1)“.”和“|”都是轉(zhuǎn)義字符区匠,必須得加“\”。
- 如果用“.”作為分隔的話帅腌,必須寫成
String.split("\\.")
驰弄,這樣才能正確的分隔開,不能用String.split(".")
速客。 - 如果用“|”作為分隔的話戚篙,必須寫成
String.split("\\|")
,這樣才能正確的分隔開挽封,不能用String.split("|")
已球。
2)如果在一個字符串中有多個分隔符臣镣,可以用“|”作為連字符,比如:“acount=? and uu =? or n=?”智亮,把三個都分隔出來忆某,可以用String.split("and|or")
。
例 :用 split() 方法對字符串進行分割的實例如下:
public static void main(String[] args) {
String Colors = "Red,Black,White,Yellow,Blue";
String[] arr1 = Colors.split(","); // 不限制元素個數(shù)
String[] arr2 = Colors.split(",", 3); // 限制元素個數(shù)為3
System.out.println("所有顏色為:");
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
System.out.println("前三個顏色為:");
for (int j = 0; j < arr2.length; j++) {
System.out.println(arr2[j]);
}
}
輸出結(jié)果如下:
所有顏色為:
Red
Black
White
Yellow Blue
前三個顏色為:
Red
Black
White,Yellow,Blue
從輸出的結(jié)果可以看出阔蛉,當指定分割字符串后組成的數(shù)組長度(大于或等于 1)時弃舒,數(shù)組的前幾個元素為字符串分割后的前幾個字符,而最后一個元素為字符串的剩余部分状原。
例如聋呢,在該實例中,指定了 arr2 的長度為 3颠区,而字符串 Colors 分割后組成的數(shù)組長度為 5削锰。因此會將 arr2 中的前兩個元素賦值為 Colors 分割后的前兩個字符,arr2 中的第 3 個元素為 Colors 字符串的后 3 個字符組成的字符串毕莱。
字符串替換
在 Java 中器贩,String 類提供了 3 種字符串替換方法,分別是 replace()朋截、replaceFirst() 和 replaceAll()蛹稍。
replace() 方法
replace() 方法用于將目標字符串中的指定字符(串)替換成新的字符(串),其語法格式如下:
字符串.replace(String oldChar, String newChar)
其中部服,oldChar 表示被替換的字符串唆姐;newChar 表示用于替換的字符串。replace() 方法會將字符串中所有 oldChar 替換成 newChar廓八。
例:創(chuàng)建一個字符串奉芦,對它使用 replace() 方法進行字符串替換并輸出結(jié)果。代碼如下:
public static void main(String[] args) {
String words = "hello java,hello php";
System.out.println("原始字符串是'"+words+"'");
System.out.println("replace(\"l\",\"D\")結(jié)果:"+words.replace("l","D"));
System.out.println("replace(\"hello\",\"你好\")結(jié)果:"+words.replace("hello","你好 "));
words = "hr's dog";
System.out.println("原始字符串是'"+words+"'");
System.out.println("replace(\"r's\",\"is\")結(jié)果:"+words.replace("r's","is"));
}
輸出結(jié)果如下所示:
原始字符串是'hello java,hello php'
replace("l","D")結(jié)果:heDDo java,heDDo php
replace("hello","你好")結(jié)果:你好 java,你好 php
原始字符串是'hr's dog'
replace("r's","is")結(jié)果:his dog
replaceFirst() 方法
replaceFirst() 方法用于將目標字符串中匹配某正則表達式的第一個子字符串替換成新的字符串剧蹂,其語法形式如下:
字符串.replaceFirst(String regex, String replacement)
其中仗阅,regex 表示正則表達式;replacement 表示用于替換的字符串国夜。例如:
String words = "hello java,hello php";
String newStr = words.replaceFirst("hello","你好 ");
System.out.println(newStr); // 輸出:你好 java,hello php
replaceAll() 方法
replaceAll() 方法用于將目標字符串中匹配某正則表達式的所有子字符串替換成新的字符串短绸,其語法形式如下:
字符串.replaceAll(String regex, String replacement)
其中车吹,regex 表示正則表達式,replacement 表示用于替換的字符串醋闭。例如:
String words = "hello java窄驹,hello php";
String newStr = words.replaceAll("hello","你好 ");
System.out.println(newStr); // 輸出:你好 java,你好 php
例子
假設(shè)有一段文本里面有很多錯誤,如錯別字≈ぢ撸現(xiàn)在使用 Java 中的字符串替換方法對它進行批量修改和糾正乐埠,其中就用到了 String 類的 replace() 方法、replaceFirst() 方法和 replaceAll() 方法。
創(chuàng)建一個 Java 類丈咐,然后在主方法 main() 中編寫代碼瑞眼,具體代碼如下所示。
public static void main(String[] args) {
// 定義原始字符串
String intro = "今天時星其天棵逊,外面時下雨天。媽米去買菜了,漏網(wǎng)在家寫作業(yè)膜毁。" + "語文作業(yè)時”其”寫 5 行后添,數(shù)學使第 10 頁。";
// 將文本中的所有"時"和"使"都替換為"是"
String newStrFirst = intro.replaceAll("[時使]", "是");
// 將文本中的所有"媽米"改為"媽媽"
String newStrSecond = newStrFirst.replaceAll("媽米", "媽媽");
// 將文本中的所有"漏網(wǎng)"改為"留我"
String newStrThird = newStrSecond.replaceAll("漏網(wǎng)", "留我");
// 將文本中第一次出現(xiàn)的"其"改為"期"
String newStrFourth = newStrThird.replaceFirst("[其]", "期");
// 輸出最終字符串
System.out.println(newStrFourth);
}
運行該程序蛙讥,輸出的正確字符串內(nèi)容如下:
今天是星期天锯蛀,外面是下雨天。媽媽去買菜了次慢,留我在家寫作業(yè)旁涤。語文作業(yè)是”其”寫 5 行,數(shù)學是第 10 頁经备。
字符串比較
字符串比較是常見的操作拭抬,包括比較相等、比較大小侵蒙、比較前綴和后綴串等造虎。在 Java 中,比較字符串的常用方法有 3 個:equals() 方法纷闺、equalsIgnoreCase() 方法算凿、 compareTo() 方法。
equals() 方法
equals() 方法將逐個地比較兩個字符串的每個字符是否相同犁功。如果兩個字符串具有相同的字符和長度氓轰,它返回 true,否則返回 false浸卦。對于字符的大小寫署鸡,也在檢查的范圍之內(nèi)。equals() 方法的語法格式如下:
str1.equals(str2);
str1 和 str2 可以是字符串變量限嫌, 也可以是字符串字面量靴庆。 例如, 下列表達式是合法的:
"Hello".equals(greeting)
下面的代碼說明了 equals() 方法的使用:
String str1 = "abc";
String str2 = new String("abc");
String str3 = "ABC";
System.out.println(str1.equals(str2)); // 輸出 trueSystem.out.println(str1.equals(str3)); // 輸出 false
例 :在第一次進入系統(tǒng)時要求管理員設(shè)置一個密碼怒医,出于安全考慮密碼需要輸入兩次炉抒,如果兩次輸入的密碼一致才生效,否則提示失敗稚叹。具體實現(xiàn)代碼如下:
public static void main(String[] args) {
String sys = "學生信息管理";
System.out.println("歡迎進入《" + sys + "》系統(tǒng)");
System.out.println("請設(shè)置一個管理員密碼:");
Scanner input = new Scanner(System.in);
String pass = input.next(); // 設(shè)置密碼
System.out.println("重復(fù)管理員密碼:");
input = new Scanner(System.in);
String pass1 = input.next(); // 確認密碼
if (pass.equals(pass1)) { // 比較兩個密碼
System.out.println("已生效焰薄,請牢記密碼:" + pass);
} else {
System.out.println("兩次密碼不一致拿诸,請重新設(shè)置。");
}
}
運行該程序塞茅,由于 equals() 方法區(qū)分大小寫亩码,所以當兩次輸入的密碼完全一致時,equals() 方法返回 true凡桥,輸出結(jié)果如下所示:
歡迎進入《學生信息管理》系統(tǒng)
請設(shè)置一個管理員密碼:
abcdef
重復(fù)管理員密碼:
abcdef
已生效蟀伸,請牢記密碼:abcdef
否則輸出如圖下所示的結(jié)果:
歡迎進入《學生信息管理》系統(tǒng)
請設(shè)置一個管理員密碼:
abcdef
重復(fù)管理員密碼:
aBcdef
兩次密碼不一致,請重新設(shè)置缅刽。
equalsIgnoreCase() 方法
equalsIgnoreCase() 方法的作用和語法與 equals() 方法完全相同啊掏,唯一不同的是 equalsIgnoreCase() 比較時不區(qū)分大小寫。當比較兩個字符串時衰猛,它會認為 A-Z 和 a-z 是一樣的迟蜜。
下面的代碼說明了 equalsIgnoreCase() 的使用:
String str1 = "abc";
String str2 = "ABC";
System.out.println(str1.equalsIgnoreCase(str2)); // 輸出 true
例:在會員系統(tǒng)中需要輸入用戶名和密碼進行檢驗,使用 equalsIgnoreCase() 方法實現(xiàn)檢驗登錄時不區(qū)分用戶名和密碼的大小寫啡省,具體的代碼實現(xiàn)如下所示娜睛。
public static void main(String[] args) {
String sys = "學生信息管理";
System.out.println("歡迎進入《" + sys + "》系統(tǒng)");
System.out.println("請輸入管理員名稱:");
Scanner input = new Scanner(System.in);
String name = input.next(); // 獲取用戶輸入的名稱
System.out.println("請輸入管理員密碼:");
input = new Scanner(System.in);
String pass = input.next(); // 獲取用戶輸入的密碼
// 比較用戶名與密碼,注意此處忽略大小寫
if (name.equalsIgnoreCase("admin") && pass.equalsIgnoreCase("somboy")) { // 驗證
System.out.println("登錄成功卦睹。");
} else {
System.out.println("登錄失敗畦戒。");
}
}
在上述代碼中,由于使用 equalsIgnoreCase() 方法進行比較结序,所以會忽略大小寫判斷障斋。因此輸入 ADMIN 和 SOMBOY 也會驗證通過,如下所示:
歡迎進入《學生信息管理》系統(tǒng)
請輸入管理員名稱:
ADMIN
請輸入管理員密碼:
SOMBOY
登錄成功徐鹤。
否則輸出結(jié)果如下所示:
歡迎進入《學生信息管理》系統(tǒng)
請輸入管理員名稱:
admin
請輸入管理員密碼:
sommboy
登錄失敗垃环。
==的比較
理解 equals() 方法和==
運算符執(zhí)行的是兩個不同的操作是重要的。如同剛才解釋的那樣返敬,equals() 方法比較字符串對象中的字符遂庄。而==
運算符比較兩個對象引用看它們是否引用相同的實例。
下面的程序說明了兩個不同的字符串(String)對象是如何能夠包含相同字符的劲赠,但同時這些對象引用是不相等的:
String s1 = "Hello";
String s2 = new String(s1);
System.out.println(s1.equals(s2)); // 輸出trueSystem.out.println(s1 == s2); // 輸出false
變量 s1 指向由“Hello”創(chuàng)建的字符串實例涛目。s2 所指的的對象是以 s1 作為初始化而創(chuàng)建的。因此這兩個字符串對象的內(nèi)容是一樣的凛澎。但它們是不同的對象泌绣,這就意味著 s1 和 s2 沒有指向同一的對象,因此它們是不==
的预厌。
因此,千萬不要使用==
運算符測試字符串的相等性元媚,以免在程序中出現(xiàn)糟糕的 bug轧叽。從表面上看苗沧,這種 bug 很像隨機產(chǎn)生的間歇性錯誤。
compareTo() 方法
通常炭晒,僅僅知道兩個字符串是否相同是不夠的待逞。對于排序應(yīng)用來說,必須知道一個字符串是大于网严、等于還是小于另一個识樱。一個字符串小于另一個指的是它在字典中先出現(xiàn)。而一個字符串大于另一個指的是它在字典中后出現(xiàn)震束。字符串(String)的 compareTo() 方法實現(xiàn)了這種功能怜庸。
compareTo() 方法用于按字典順序比較兩個字符串的大小,該比較是基于字符串各個字符的 Unicode 值垢村。compareTo() 方法的語法格式如下:
str.compareTo(String otherstr);
它會按字典順序?qū)?str 表示的字符序列與 otherstr 參數(shù)表示的字符序列進行比較割疾。如果按字典順序 str 位于 otherster 參數(shù)之前,比較結(jié)果為一個負整數(shù)嘉栓;如果 str 位于 otherstr 之后宏榕,比較結(jié)果為一個正整數(shù);如果兩個字符串相等侵佃,則結(jié)果為 0麻昼。
提示:如果兩個字符串調(diào)用 equals() 方法返回 true,那么調(diào)用 compareTo() 方法會返回 0馋辈。
例:編寫一個簡單的 Java 程序抚芦,演示 compareTo() 方法比較字符串的用法,以及返回值的區(qū)別首有。代碼如下:
public static void main(String[] args) {
String str = "A";
String str1 = "a";
System.out.println("str=" + str);
System.out.println("str1=" + str1);
System.out.println("str.compareTo(str1)的結(jié)果是:" + str.compareTo(str1));
System.out.println("str1.compareTo(str)的結(jié)果是:" + str1.compareTo(str));
System.out.println("str1.compareTo('a')的結(jié)果是:" + str1.compareTo("a"));
}
上述代碼定義了兩個字符串“A”和“a”燕垃,然后調(diào)用 compareTo() 方法進行相互比較。最后一行代碼拿“a”與“a”進行比較井联,由于兩個字符串相同比較結(jié)果為 0卜壕。運行后的輸出結(jié)果如下:
str = A
str1 = a
str.compareTo(str1)的結(jié)果是:-32
str1.compareTo(str)的結(jié)果是:32
str1.compareTo('a')的結(jié)果是:0
字符串查找
在給定的字符串中查找字符或字符串是比較常見的操作。字符串查找分為兩種形式:一種是在字符串中獲取匹配字符(串)的索引值烙常,另一種是在字符串中獲取指定索引位置的字符轴捎。
根據(jù)字符查找
String 類的 indexOf() 方法和 lastlndexOf() 方法用于在字符串中獲取匹配字符(串)的索引值。
indexOf() 方法
indexOf() 方法用于返回字符(串)在指定字符串中首次出現(xiàn)的索引位置蚕脏,如果能找到侦副,則返回索引值,否則返回 -1驼鞭。該方法主要有兩種重載形式:
str.indexOf(value)str.indexOf(value,int fromIndex)
其中秦驯,str 表示指定字符串;value 表示待查找的字符(串)挣棕;fromIndex 表示查找時的起始索引译隘,如果不指定 fromIndex亲桥,則默認從指定字符串中的開始位置(即 fromIndex 默認為 0)開始查找。
例如固耘,下列代碼在字符串“Hello Java”中查找字母 v 的索引位置题篷。
String s = "Hello Java";
int size = s.indexOf('v'); // size的結(jié)果為8
上述代碼執(zhí)行后 size 的結(jié)果為 8,它的查找過程如圖 1 所示厅目。
例:編寫一個簡單的 Java 程序番枚,演示 indexOf() 方法查找字符串的用法,并輸出結(jié)果损敷。代碼如下:
public static void main(String[] args) {
String words = "today,monday,sunday";
System.out.println("原始字符串是'"+words+"'");
System.out.println("indexOf(\"day\")結(jié)果:"+words.indexOf("day"));
System.out.println("indexOf(\"day\",5)結(jié)果:"+words.indexOf("day",5));
System.out.println("indexOf(\"o\")結(jié)果:"+words.indexOf("o"));
System.out.println("indexOf(\"o\",6)結(jié)果:"+words.indexOf("o",6));
}
運行后的輸出結(jié)果如下:
原始字符串是'today,monday,sunday'
indexOf("day")結(jié)果:2
indexOf("day",5)結(jié)果:9
indexOf("o")結(jié)果:1
indexOf("o",6)結(jié)果:7
lastlndexOf() 方法
lastIndexOf() 方法用于返回字符(串)在指定字符串中最后一次出現(xiàn)的索引位置葫笼,如果能找到則返回索引值,否則返回 -1嗤锉。該方法也有兩種重載形式:
str.lastIndexOf(value)str.lastlndexOf(value, int fromIndex)
注意:lastIndexOf() 方法的查找策略是從右往左查找渔欢,如果不指定起始索引,則默認從字符串的末尾開始查找瘟忱。
例 :編寫一個簡單的 Java 程序奥额,演示 lastIndexOf() 方法查找字符串的用法,并輸出結(jié)果访诱。代碼如下:
public static void main(String[] args) {
String words="today,monday,Sunday";
System.out.println("原始字符串是'"+words+"'");
System.out.println("lastIndexOf(\"day\")結(jié)果:"+words.lastIndexOf("day"));
System.out.println("lastIndexOf(\"day\",5)結(jié)果:"+words.lastIndexOf("day",5));
System.out.println("lastIndexOf(\"o\")結(jié)果:"+words.lastIndexOf("o"));
System.out.println("lastlndexOf(\"o\",6)結(jié)果:"+words.lastIndexOf("o",6));
}
運行后的輸出結(jié)果如下:
原始字符串是'today,monday,Sunday'
lastIndexOf("day")結(jié)果:16
lastIndexOf("day",5)結(jié)果:2
lastIndexOf("o")結(jié)果:7
lastlndexOf("o",6)結(jié)果:1
根據(jù)索引查找
String 類的 charAt() 方法可以在字符串內(nèi)根據(jù)指定的索引查找字符垫挨,該方法的語法形式如下:
字符串名.charAt(索引值)
提示:字符串本質(zhì)上是字符數(shù)組,因此它也有索引触菜,索引從零開始九榔。
charAt() 方法的使用示例如下:
String words = "today,monday,sunday";
System.out.println(words.charAt(0)); // 結(jié)果:t
System.out.println(words.charAt(1)); // 結(jié)果:o
System.out.println(words.charAt(8)); // 結(jié)果:n
StringBuffer類詳解
在 Java 中,除了通過 String 類創(chuàng)建和處理字符串之外涡相,還可以使用 StringBuffer 類來處理字符串哲泊。StringBuffer 類可以比 String 類更高效地處理字符串。
因為 StringBuffer 類是可變字符串類催蝗,創(chuàng)建 StringBuffer 類的對象后可以隨意修改字符串的內(nèi)容切威。每個 StringBuffer 類的對象都能夠存儲指定容量的字符串,如果字符串的長度超過了 StringBuffer 類對象的容量丙号,則該對象的容量會自動擴大先朦。
創(chuàng)建 StringBuffer 類
StringBuffer 類提供了 3 個構(gòu)造方法來創(chuàng)建一個字符串,如下所示:
- StringBuffer() 構(gòu)造一個空的字符串緩沖區(qū)犬缨,并且初始化為 16 個字符的容量喳魏。
- StringBuffer(int length) 創(chuàng)建一個空的字符串緩沖區(qū),并且初始化為指定長度 length 的容量怀薛。
- StringBuffer(String str) 創(chuàng)建一個字符串緩沖區(qū)刺彩,并將其內(nèi)容初始化為指定的字符串內(nèi)容 str,字符串緩沖區(qū)的初始容量為 16 加上字符串 str 的長度。
使用 StringBuffer 類的構(gòu)造函數(shù)的示例如下:
// 定義一個空的字符串緩沖區(qū)迂苛,含有16個字符的容量
StringBuffer str1 = new StringBuffer();
// 定義一個含有10個字符容量的字符串緩沖區(qū)
StringBuffer str2 = new StringBuffer(10);
// 定義一個含有(16+4)的字符串緩沖區(qū)三热,"青春無悔"為4個字符
StringBuffer str3 = new StringBuffer("青春無悔");
/*
*輸出字符串的容量大小
*capacity()方法返回字符串的容量大小
*/
System.out.println(str1.capacity()); // 輸出 16
System.out.println(str2.capacity()); // 輸出 10
System.out.println(str3.capacity()); // 輸出 20
上述代碼聲明了 3 個 StringBuffer 對象 str1、str2 和 str3三幻,并分別對其進行初始化。str1.capacity() 用于查看 str1 的容量呐能,接著以同樣的方式對 str2 和 str3 進行容量查看的操作念搬。
追加字符串
StringBuffer 類的 append() 方法用于向原有 StringBuffer 對象中追加字符串。該方法的語法格式如下:
StringBuffer 對象.append(String str)
該方法的作用是追加內(nèi)容到當前 StringBuffer 對象的末尾摆出,類似于字符串的連接朗徊。調(diào)用該方法以后,StringBuffer 對象的內(nèi)容也發(fā)生了改變偎漫,例如:
StringBuffer buffer = new StringBuffer("hello,"); // 創(chuàng)建一個 StringBuffer 對象
String str = "World!";buffer.append(str); // 向 StringBuffer 對象追加 str 字符串
System.out.println(buffer.substring(0)); // 輸出:Hello,World!
替換字符
StringBuffer 類的 setCharAt() 方法用于在字符串的指定索引位置替換一個字符爷恳。該方法的語法格式如下:
StringBuffer 對象.setCharAt(int index, char ch);
該方法的作用是修改對象中索引值為 index 位置的字符為新的字符 ch,例如:
StringBuffer sb = new StringBuffer("hello");
sb.setCharAt(1,'E');System.out.println(sb); // 輸出:hEllosb.setCharAt(0,'H');
System.out.println(sb); // 輸出:HEllosb.setCharAt(2,'p');
System.out.println(sb); // 輸出:HEplo
反轉(zhuǎn)字符串
StringBuffer 類中的 reverse() 方法用于將字符串序列用其反轉(zhuǎn)的形式取代象踊。該方法的語法格式如下:
StringBuffer 對象.reverse();
使用 StringBuffer 類中的 reverse() 方法對字符串進行反轉(zhuǎn)的示例如下:
StringBuffer sb = new StringBuffer("java");
sb.reverse();
System.out.println(sb); // 輸出:avaj
刪除字符串
StringBuffer 類提供了 deleteCharAt() 和 delete() 兩個刪除字符串的方法温亲。
deleteCharAt() 方法
deleteCharAt() 方法用于移除序列中指定位置的字符,該方法的語法格式如下:
StringBuffer 對象.deleteCharAt(int index);
deleteCharAt() 方法的作用是刪除指定位置的字符杯矩,然后將剩余的內(nèi)容形成一個新的字符串栈虚。例如:
StringBuffer sb = new StringBuffer("She");sb.deleteCharAt(2);System.out.println(sb); // 輸出:Se
執(zhí)行該段代碼,將字符串 sb 中索引值為 2 的字符刪除史隆,剩余的內(nèi)容組成一個新的字符串魂务,因此對象 sb 的值為 Se。
delete() 方法
delete() 方法用于移除序列中子字符串的字符泌射,該方法的語法格式如下:
StringBuffer 對象.delete(int start,int end);
其中粘姜,start 表示要刪除字符的起始索引值(包括索引值所對應(yīng)的字符),end 表示要刪除字符串的結(jié)束索引值(不包括索引值所對應(yīng)的字符)熔酷。該方法的作用是刪除指定區(qū)域以內(nèi)的所有字符孤紧,例如:
StringBuffer sb = new StringBuffer("hello jack");
sb.delete(2,5);System.out.println(sb); // 輸出:he jack
sb.delete(2,5);System.out.println(sb); // 輸出:heck
執(zhí)行該段代碼,將字符串“hello jack”索引值為 2(包括)到索引值為 5(不包括)之間的所有字符刪除纯陨,因此輸出的新的字符串的值為“he jack”坛芽。
String、StringBuffer和StringBuilder類的區(qū)別
在 Java 中字符串屬于對象翼抠,Java 提供了 String 類來創(chuàng)建和操作字符串咙轩。String 類是不可變類,即一旦一個 String 對象被創(chuàng)建以后阴颖,包含在這個對象中的字符序列是不可改變的活喊,直至這個對象被銷毀。
Java 提供了兩個可變字符串類 StringBuffer 和 StringBuilder量愧,中文翻譯為“字符串緩沖區(qū)”钾菊。
StringBuilder 類是 JDK 1.5 新增的類帅矗,它也代表可變字符串對象。實際上煞烫,StringBuilder 和 StringBuffer 功能基本相似浑此,方法也差不多。不同的是滞详,StringBuffer 是線程安全的凛俱,而 StringBuilder 則沒有實現(xiàn)線程安全功能,所以性能略高料饥。因此在通常情況下蒲犬,如果需要創(chuàng)建一個內(nèi)容可變的字符串對象,則應(yīng)該優(yōu)先考慮使用 StringBuilder 類岸啡。
StringBuffer原叮、StringBuilder、String 中都實現(xiàn)了 CharSequence 接口巡蘸。CharSequence 是一個定義字符串操作的接口奋隶,它只包括 length()、charAt(int index)赡若、subSequence(int start, int end) 這幾個 API达布。
StringBuffer、StringBuilder逾冬、String 對 CharSequence 接口的實現(xiàn)過程不一樣黍聂,如下圖 所示:
可見,String 直接實現(xiàn)了 CharSequence 接口身腻,StringBuilder 和 StringBuffer 都是可變的字符序列产还,它們都繼承于 AbstractStringBuilder,實現(xiàn)了 CharSequence 接口嘀趟。
總結(jié)
String 是 Java 中基礎(chǔ)且重要的類脐区,被聲明為 final class,是不可變字符串她按。因為它的不可變性牛隅,所以拼接字符串時候會產(chǎn)生很多無用的中間對象,如果頻繁的進行這樣的操作對性能有所影響酌泰。
StringBuffer 就是為了解決大量拼接字符串時產(chǎn)生很多中間對象問題而提供的一個類媒佣。它提供了 append 和 add 方法,可以將字符串添加到已有序列的末尾或指定位置陵刹,它的本質(zhì)是一個線程安全的可修改的字符序列默伍。
在很多情況下我們的字符串拼接操作不需要線程安全,所以 StringBuilder 登場了。StringBuilder 是 JDK1.5 發(fā)布的也糊,它和 StringBuffer 本質(zhì)上沒什么區(qū)別炼蹦,就是去掉了保證線程安全的那部分,減少了開銷狸剃。
線程安全:
StringBuffer:線程安全
StringBuilder:線程不安全
速度:
一般情況下掐隐,速度從快到慢為 StringBuilder > StringBuffer > String,當然這是相對的钞馁,不是絕對的瑟枫。
使用環(huán)境:
操作少量的數(shù)據(jù)使用 String。
單線程操作大量數(shù)據(jù)使用 StringBuilder指攒。
多線程操作大量數(shù)據(jù)使用 StringBuffer秸讹。
正則表達式詳解
本節(jié)了解即可
正則表達式(Regular Expression)又稱正規(guī)表示法策吠、常規(guī)表示法丈探,在代碼中常簡寫為 regex膏潮、regexp 或 RE栖博,它是計算機科學的一個概念咏瑟。
正則表達式是一個強大的字符串處理工具攘滩,可以對字符串進行查找喧伞、提取狞山、分割全闷、替換等操作,是一種可以用于模式匹配和替換的規(guī)范萍启。一個正則表達式就是由普通的字符(如字符 a~z)以及特殊字符(元字符)組成的文字模式总珠,它用以描述在查找文字主體時待匹配的一個或多個字符串。
String 類里也提供了如下幾個特殊的方法勘纯。
- boolean matches(String regex):判斷該字符串是否匹配指定的正則表達式局服。
- String replaceAll(String regex, String replacement):將該字符串中所有匹配 regex 的子串替換成 replacement。
- String replaceFirst(String regex, String replacement):將該字符串中第一個匹配 regex 的子串替換成 replacement驳遵。
- String[] split(String regex):以 regex 作為分隔符淫奔,把該字符串分割成多個子串。
上面這些特殊的方法都依賴于 Java 提供的正則表達式支持堤结,除此之外唆迁,Java 還提供了 Pattern 和 Matcher 兩個類專門用于提供正則表達式支持。
很多人都會覺得正則表達式是一個非常神奇竞穷、高級的知識唐责,其實正則表達式是一種非常簡單而且非常實用的工具。正則表達式是一個用于匹配字符串的模板来庭。實際上妒蔚,任意字符串都可以當成正則表達式使用。例如“abc”,它也是一個正則表達式肴盏,只是它只能匹配“abc”字符串科盛。
如果正則表達式僅能匹配“abc”這樣的字符串,那么正則表達式也就不值得學習了菜皂。正則表達式作為一個用于匹配字符串的模板贞绵,將某個字符模式與所搜索的字符串進行匹配。本文簡單了解一下如何使用正則表達式來操作字符串恍飘。
正則表達式支持字符
創(chuàng)建正則表達式就是創(chuàng)建一個特殊的字符串榨崩。正則表達式所支持的合法字符如表所示。
字符 | 解釋 |
---|---|
X | 字符x(x 可代表任何合法的字符) |
\0mnn | 八進制數(shù) 0mnn 所表示的字符 |
\xhh | 十六進制值 0xhh 所表示的字符 |
\uhhhh | 十六進制值 0xhhhh 所表示的 Unicode 字符 |
\t | 制表符(“\u0009”) |
\n | 新行(換行)符(‘\u000A’) |
\r | 回車符(‘\u000D’) |
\f | 換頁符(‘\u000C’) |
\a | 報警(bell)符(‘\u0007’) |
\e | Escape 符(‘\u001B’) |
\cx | x 對應(yīng)的的控制符章母。例如母蛛,\cM 匹配 Ctrl-M。x 值必須為 A~Z 或 a~z 之一乳怎。 |
除此之外彩郊,正則表達式中有一些特殊字符,這些特殊字符在正則表達式中有其特殊的用途蚪缀,比如前面介紹的反斜線\
秫逝。
如果需要匹配這些特殊字符,就必須首先將這些字符轉(zhuǎn)義询枚,也就是在前面添加一個反斜線\
违帆。正則表達式中的特殊字符如表所示。
特殊字符 | 說明 |
---|---|
$ | 匹配一行的結(jié)尾金蜀。要匹配 |
^ | 匹配一行的開頭。要匹配 ^ 字符本身廉油,請使用\^
|
() | 標記子表達式的開始和結(jié)束位置惠险。要匹配這些字符,請使用\( 和\)
|
[] | 用于確定中括號表達式的開始和結(jié)束位置抒线。要匹配這些字符班巩,請使用\[ 和\]
|
{} | 用于標記前面子表達式的出現(xiàn)頻度。要匹配這些字符嘶炭,請使用\{ 和\}
|
* | 指定前面子表達式可以出現(xiàn)零次或多次抱慌。要匹配 * 字符本身,請使用\*
|
+ | 指定前面子表達式可以出現(xiàn)一次或多次眨猎。要匹配 + 字符本身抑进,請使用\+
|
? | 指定前面子表達式可以出現(xiàn)零次或一次。要匹配 睡陪?字符本身寺渗,請使用\?
|
. | 匹配除換行符\n 之外的任何單字符匿情。要匹配. 字符本身,請使用\.
|
\ | 用于轉(zhuǎn)義下一個字符信殊,或指定八進制炬称、十六進制字符。如果需匹配\ 字符涡拘,請用\\
|
| | 指定兩項之間任選一項玲躯。如果要匹配丨 字符本身,請使用|
|
將上面多個字符拼起來鳄乏,就可以創(chuàng)建一個正則表達式跷车。例如:
"\u0041\\" // 匹配 A
"\u0061\t" // 匹配a<制表符>
"\?\[" // 匹配?[
注意:可能大家會覺得第一個正則表達式中怎么有那么多反斜杠橱野?這是由于 Java 字符串中反斜杠本身需要轉(zhuǎn)義朽缴,因此兩個反斜杠(\)實際上相當于一個(前一個用于轉(zhuǎn)義)。
上面的正則表達式依然只能匹配單個字符水援,這是因為還未在正則表達式中使用“通配符”不铆,“通配符”是可以匹配多個字符的特殊字符。正則表達式中的“通配符”遠遠超出了普通通配符的功能裹唆,它被稱為預(yù)定義字符,正則表達式支持如表 3 所示的預(yù)定義字符只洒。
預(yù)定義字符 | 說明 |
---|---|
. | 可以匹配任何字符 |
\d | 匹配 0~9 的所有數(shù)字 |
\D | 匹配非數(shù)字 |
\s | 匹配所有的空白字符许帐,包括空格、制表符毕谴、回車符成畦、換頁符、換行符等 |
\S | 匹配所有的非空白字符 |
\w | 匹配所有的單詞字符涝开,包括 0~9 所有數(shù)字循帐、26 個英文字母和下畫線_
|
\W | 匹配所有的非單詞字符 |
上面的 7 個預(yù)定義字符其實很容易記憶,其中:
- d 是 digit 的意思舀武,代表數(shù)字拄养。
- s 是 space 的意思,代表空白银舱。
- w 是 word 的意思瘪匿,代表單詞。
- d寻馏、s棋弥、w 的大寫形式恰好匹配與之相反的字符。
有了上面的預(yù)定義字符后诚欠,接下來就可以創(chuàng)建更強大的正則表達式了顽染。例如:
c\wt // 可以匹配cat漾岳、cbt、cct粉寞、cOt尼荆、c9t等一批字符串
\d\d\d-\d\d\d-\d\d\d\d // 匹配如 000-000-0000 形式的電話號碼
在一些特殊情況下,例如仁锯,若只想匹配 a~f 的字母耀找,或者匹配除 ab 之外的所有小寫字母,或者匹配中文字符业崖,上面這些預(yù)定義字符就無能為力了野芒,此時就需要使用方括號表達式,方括號表達式有如表 4 所示的幾種形式双炕。
方括號表達式 | 說明 |
---|---|
表示枚舉 | 例如[abc] 表示 a狞悲、b、c 其中任意一個字符妇斤;[gz] 表示 g摇锋、z 其中任意一個字符 |
表示范圍:- | 例如[a-f] 表示 a~f 范圍內(nèi)的任意字符;[\\u0041-\\u0056] 表示十六進制字符 \u0041 到 \u0056 范圍的字符站超。范圍可以和枚舉結(jié)合使用荸恕,如[a-cx-z] ,表示 ac死相、xz 范圍內(nèi)的任意字符 |
表示求否:^ | 例如[^abc] 表示非 a融求、b、c 的任意字符算撮;[^a-f] 表示不是 a~f 范圍內(nèi)的任意字符 |
表示“與”運算:&& | 例如 [a-z&&[def]] 是 a~z 和 [def] 的交集生宛,表示 d、e f[a-z&&^bc]] 是 a~z 范圍內(nèi)的所有字符肮柜,除 b 和 c 之外 [ad-z] [a-z&&[m-p]] 是 a~z 范圍內(nèi)的所有字符陷舅,除 m~p 范圍之外的字符 |
表示“并”運算 | 并運算與前面的枚舉類似。例如[a-d[m-p]] 表示 [a-dm-p] |
方括號表達式比前面的預(yù)定義字符靈活多了审洞,幾乎可以匹配任何字符莱睁。例如,若需要匹配所有的中文字符芒澜,就可以利用 [\u0041-\u0056] 形式——因為所有中文字符的 Unicode 值是連續(xù)的缩赛,只要找出所有中文字符中最小、最大的 Unicode 值撰糠,就可以利用上面形式來匹配所有的中文字符酥馍。
正則表達式還支持圓括號,用于將多個表達式組成一個子表達式阅酪,圓括號中可以使用或運算符|
旨袒。例如汁针,正則表達式“((public)|(protected)|(private))”用于匹配 Java 的三個訪問控制符其中之一。
除此之外砚尽,Java 正則表達式還支持如表 5 所示的幾個邊界匹配符施无。
邊界匹配符 | 說明 |
---|---|
^ | 行的開頭 |
$ | 行的結(jié)尾 |
\b | 單詞的邊界 |
\B | 非單詞的邊界 |
\A | 輸入的開頭 |
\G | 前一個匹配的結(jié)尾 |
\Z | 輸入的結(jié)尾,僅用于最后的結(jié)束符 |
\z | 輸入的結(jié)尾 |
前面例子中需要建立一個匹配 000-000-0000 形式的電話號碼時必孤,使用了 \d\d\d-\d\d\d-\d\d\d\d 正則表達式猾骡,這看起來比較煩瑣。實際上敷搪,正則表達式還提供了數(shù)量標識符兴想,正則表達式支持的數(shù)量標識符有如下幾種模式。
- Greedy(貪婪模式):數(shù)量表示符默認采用貪婪模式赡勘,除非另有表示嫂便。貪婪模式的表達式會一直匹配下去,直到無法匹配為止闸与。如果你發(fā)現(xiàn)表達式匹配的結(jié)果與預(yù)期的不符毙替,很有可能是因為你以為表達式只會匹配前面幾個字符,而實際上它是貪婪模式践樱,所以會一直匹配下去厂画。
- Reluctant(勉強模式):用問號后綴(?)表示,它只會匹配最少的字符拷邢。也稱為最小匹配模式木羹。
- Possessive(占有模式):用加號后綴(+)表示,目前只有 Java 支持占有模式解孙,通常比較少用。
三種模式的數(shù)量表示符如表 6 所示抛人。
貪婪模式 | 勉強模式 | 占用模式 | 說明 |
---|---|---|---|
X? | X?? | X?+ | X表達式出現(xiàn)零次或一次 |
X* | X*? | X*+ | X表達式出現(xiàn)零次或多次 |
X+ | X+? | X++ | X表達式出現(xiàn)一次或多次 |
X{n} | X{n}? | X{n}+ | X表達式出現(xiàn) n 次 |
X{n,} | X{n,}? | X{n,}+ | X表達式最少出現(xiàn) n 次 |
X{n,m} | X{n,m}? | X{n,m}+ | X表達式最少出現(xiàn) n 次弛姜,最多出現(xiàn) m 次 |
關(guān)于貪婪模式和勉強模式的對比,看如下代碼:
String str = "hello,java!";
// 貪婪模式的正則表達式
System.out.println(str.replaceFirst("\\w*" , "■")); //輸出■,java!
// 勉強模式的正則表達式
System.out.println(str.replaceFirst("\\w*?" , "■"")); //輸出■hello, java!
當從“hello java!”字符串中查找匹配\\w*
子串時妖枚,因為\w*
使用了貪婪模式廷臼,數(shù)量表示符*
會一直匹配下去,所以該字符串前面的所有單詞字符都被它匹配到绝页,直到遇到空格荠商,所以替換后的效果是“■,Java!”续誉;如果使用勉強模式莱没,數(shù)量表示符*
會盡量匹配最少字符,即匹配 0 個字符酷鸦,所以替換后的結(jié)果是“■hello饰躲,java!”牙咏。
Pattern類和Matcher類的使用
java.util.regex 是一個用正則表達式所訂制的模式來對字符串進行匹配工作的類庫包。它包括兩個類:Pattern 和 Matcher嘹裂。
Pattern 對象是正則表達式編譯后在內(nèi)存中的表示形式妄壶,因此,正則表達式字符串必須先被編譯為 Pattern 對象寄狼,然后再利用該 Pattern 對象創(chuàng)建對應(yīng)的 Matcher 對象丁寄。執(zhí)行匹配所涉及的狀態(tài)保留在 Matcher 對象中,多個 Matcher 對象可共享同一個 Pattern 對象泊愧。
因此伊磺,典型的調(diào)用順序如下:
// 將一個字符串編譯成 Pattern 對象
Pattern p = Pattern.compile("a*b");
// 使用 Pattern 對象創(chuàng)建 Matcher 對象
Matcher m = p.matcher("aaaaab");
boolean b = m.matches(); // 返回 true
上面定義的 Pattern 對象可以多次重復(fù)使用。如果某個正則表達式僅需一次使用拼卵,則可直接使用 Pattern 類的靜態(tài) matches() 方法奢浑,此方法自動把指定字符串編譯成匿名的 Pattern 對象,并執(zhí)行匹配腋腮,如下所示雀彼。
boolean b = Pattern.matches ("a*b","aaaaab"); // 返回 true
上面語句等效于前面的三條語句。但采用這種語句每次都需要重新編譯新的 Pattern 對象即寡,不能重復(fù)利用已編譯的 Pattern 對象徊哑,所以效率不高。Pattern 是不可變類聪富,可供多個并發(fā)線程安全使用莺丑。
Matcher 類提供了幾個常用方法,如表所示墩蔓。
名稱 | 說明 |
---|---|
find() | 返回目標字符串中是否包含與 Pattern 匹配的子串 |
group() | 返回上一次與 Pattern 匹配的子串 |
start() | 返回上一次與 Pattern 匹配的子串在目標字符串中的開始位置 |
end() | 返回上一次與 Pattern 匹配的子串在目標字符串中的結(jié)束位置加 1 |
lookingAt() | 返回目標字符串前面部分與 Pattern 是否匹配 |
matches() | 返回整個目標字符串與 Pattern 是否匹配 |
reset() | 將現(xiàn)有的 Matcher 對象應(yīng)用于一個新的字符序列梢莽。 |
在 Pattern、Matcher 類的介紹中經(jīng)常會看到一個 CharSequence 接口奸披,該接口代表一個字符序列昏名,其中 CharBuffer、String阵面、StringBuffer轻局、StringBuilder 都是它的實現(xiàn)類。簡單地說样刷,CharSequence 代表一個各種表示形式的字符串仑扑。
通過 Matcher 類的 find() 和 group() 方法可以從目標字符串中依次取出特定子串(匹配正則表達式的子串),例如互聯(lián)網(wǎng)的網(wǎng)絡(luò)爬蟲置鼻,它們可以自動從網(wǎng)頁中識別出所有的電話號碼镇饮。下面程序示范了如何從大段的字符串中找出電話號碼。
public class FindGroup {
public static void main(String[] args) {
// 使用字符串模擬從網(wǎng)絡(luò)上得到的網(wǎng)頁源碼
String str = "我想找一套適合自己的JAVA教程箕母,盡快聯(lián)系我13500006666" + "交朋友盒让,電話號碼是13611125565" + "出售二手電腦梅肤,聯(lián)系方式15899903312";
// 創(chuàng)建一個Pattern對象,并用它建立一個Matcher對象
// 該正則表達式只抓取13X和15X段的手機號
// 實際要抓取哪些電話號碼邑茄,只要修改正則表達式即可
Matcher m = Pattern.compile("((13\\d)|(15\\d))\\d{8}").matcher(str);
// 將所有符合正則表達式的子串(電話號碼)全部輸出
while (m.find()) {
System.out.println(m.group());
}
}
}
運行上面程序姨蝴,看到如下運行結(jié)果:
13500006666
13611125565
15899903312
從上面運行結(jié)果可以看出,find() 方法依次查找字符串中與 Pattern 匹配的子串肺缕,一旦找到對應(yīng)的子串左医,下次調(diào)用 find() 方法時將接著向下查找。
提示:通過程序運行結(jié)果可以看出同木,使用正則表達式可以提取網(wǎng)頁上的電話號碼浮梢,也可以提取郵件地址等信息。如果程序再進一步彤路,可以從網(wǎng)頁上提取超鏈接信息秕硝,再根據(jù)超鏈接打開其他網(wǎng)頁,然后在其他網(wǎng)頁上重復(fù)這個過程就可以實現(xiàn)簡單的網(wǎng)絡(luò)爬蟲了洲尊。
find() 方法還可以傳入一個 int 類型的參數(shù)远豺,帶 int 參數(shù)的 find() 方法將從該 int 索引處向下搜索。start() 和 end() 方法主要用于確定子串在目標字符串中的位置坞嘀,如下程序所示躯护。
public class StartEnd {
public static void main(String[] args) {
// 創(chuàng)建一個Pattern對象,并用它建立一個Matcher對象
String regStr = "Java is very easy!";
System.out.println("目標字符串是:" + regStr);
Matcher m = Pattern.compile("\\w+").matcher(regStr);
while (m.find()) {
System.out.println(m.group() + "子串的起始位置:" + m.start() + "丽涩,其結(jié)束位置:" + m.end());
}
}
}
上面程序使用 find()棺滞、group() 方法逐項取出目標字符串中與指定正則表達式匹配的子串,并使用 start()矢渊、end() 方法返回子串在目標字符串中的位置继准。運行上面程序,看到如下運行結(jié)果:
目標字符串是:Java is very easy!
Java子串的起始位置:0矮男,其結(jié)束位置:4
is子串的起始位置:5移必,其結(jié)束位置:7
very子串的起始位置:8,其結(jié)束位置:12
easy子串的起始位置:13昂灵,其結(jié)束位置:17
matches() 和 lookingAt() 方法有點相似,只是 matches() 方法要求整個字符串和 Pattern 完全匹配時才返回 true舞萄,而 lookingAt() 只要字符串以 Pattern 開頭就會返回 true眨补。reset() 方法可將現(xiàn)有的 Matcher 對象應(yīng)用于新的字符序列〉古В看如下例子程序撑螺。
public class MatchesTest {
public static void main(String[] args) {
String[] mails = { "kongyeeku@163.com", "kongyeeku@gmail.com", "ligang@crazyit.org", "wawa@abc.xx" };
String mailRegEx = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";
Pattern mailPattern = Pattern.compile(mailRegEx);
Matcher matcher = null;
for (String mail : mails) {
if (matcher == null) {
matcher = mailPattern.matcher(mail);
} else {
matcher.reset(mail);
}
String result = mail + (matcher.matches() ? "是" : "不是") + "一個有效的郵件地址!";
System.out.println(result);
}
}
}
上面程序創(chuàng)建了一個郵件地址的 Pattern崎弃,接著用這個 Pattern 與多個郵件地址進行匹配甘晤。當程序中的 Matcher 為 null 時含潘,程序調(diào)用 matcher() 方法來創(chuàng)建一個 Matcher 對象,一旦 Matcher 對象被創(chuàng)建线婚,程序就調(diào)用 Matcher 的 reset() 方法將該 Matcher 應(yīng)用于新的字符序列遏弱。
從某個角度來看,Matcher 的 matches()塞弊、lookingAt() 和 String 類的 equals() 有點相似。區(qū)別是 String 類的 equals() 都是與字符串進行比較,而 Matcher 的 matches() 和 lookingAt() 則是與正則表達式進行匹配肠槽。
事實上翅溺,String 類里也提供了 matches() 方法,該方法返回該字符串是否匹配指定的正則表達式诀黍。例如:
"kongyeeku@163.com".matches("\\w{3,20}@\\w+\\.(com|org|cn|net|gov)"); // 返回 true
除此之外袋坑,還可以利用正則表達式對目標字符串進行分割、查找眯勾、替換等操作枣宫,看如下例子程序。
public class ReplaceTest {
public static void main(String[] args) {
String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",
"Java represses oracular expressions" };
Pattern p = Pattern.compile("re\\w*");
Matcher matcher = null;
for (int i = 0; i < msgs.length; i++) {
if (matcher == null) {
matcher = p.matcher(msgs[i]);
} else {
matcher.reset(msgs[i]);
}
System.out.println(matcher.replaceAll("哈哈:)"));
}
}
}
上面程序使用了 Matcher 類提供的 replaceAll() 把字符串中所有與正則表達式匹配的子串替換成“哈哈:)”咒精,實際上镶柱,Matcher 類還提供了一個 replaceFirst(),該方法只替換第一個匹配的子串模叙。運行上面程序歇拆,會看到字符串中所有以“re”開頭的單詞都會被替換成“哈哈:)”。
實際上范咨,String 類中也提供了 replaceAll()故觅、replaceFirst()、split() 等方法渠啊。下面的例子程序直接使用 String 類提供的正則表達式功能來進行替換和分割输吏。
public class StringReg {
public static void main(String[] args) {
String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",
"Java represses oracular expressions" };
for (String msg : msgs) {
System.out.println(msg.replaceFirst("re\\w*", "哈哈:)"));
System.out.println(Arrays.toString(msg.split(" ")));
}
}
}
上面程序只使用 String 類的 replaceFirst() 和 split() 方法對目標字符串進行了一次替換和分割。運行上面程序替蛉,會看到如下所示的輸出結(jié)果贯溅。
Java has 哈哈:) expressions in 1.4
[Java, has, regular, expressions, in, 1.4]
哈哈:) expressions now expressing in Java
[regular, expressions, now, expressing, in, Java]
Java 哈哈:) oracular expressions
[Java, represses, oracular, expressions]
正則表達式是一個功能非常靈活的文本處理工具,增加了正則表達式支持后的 Java躲查,可以不再使用 StringTokenizer 類(也是一個處理字符串的工具它浅,但功能遠不如正則表達式強大)即可進行復(fù)雜的字符串處理。
數(shù)字處理
Math類的常用方法
Java 中的 +镣煮、-姐霍、*、/ 和 % 等基本算術(shù)運算符不能進行更復(fù)雜的數(shù)學運算,例如镊折,三角函數(shù)胯府、對數(shù)運算、指數(shù)運算等恨胚。于是 Java 提供了 Math 工具類來完成這些復(fù)雜的運算骂因。
在 Java 中 Math 類封裝了常用的數(shù)學運算,提供了基本的數(shù)學操作与纽,如指數(shù)侣签、對數(shù)、平方根和三角函數(shù)等急迂。Math 類位于 java.lang 包影所,它的構(gòu)造方法是 private 的,因此無法創(chuàng)建 Math 類的對象僚碎,并且 Math 類中的所有方法都是類方法猴娩,可以直接通過類名來調(diào)用它們。
下面詳細介紹該類的常量及數(shù)學處理方法勺阐。
靜態(tài)常量
Math 類中包含 E 和 PI 兩個靜態(tài)常量卷中,正如它們名字所暗示的,它們的值分別等于 e(自然對數(shù))和 π(圓周率)渊抽。
例:調(diào)用 Math 類的 E 和 PI 兩個常量蟆豫,并將結(jié)果輸出。代碼如下:
System.out.println("E 常量的值:" + Math.E);
System.out.println("PI 常量的值:" + Math.PI);
執(zhí)行上述代碼懒闷,輸出結(jié)果如下:
E 常量的值:2.718281828459045
PI 常量的值:3.141592653589793
求最大值十减、最小值和絕對值
在程序中常見的就是求最大值、最小值和絕對值問題愤估,如果使用 Math 類提供的方法可以很容易實現(xiàn)帮辟。這些方法的說明如表 1 所示。
方法 | 說明 |
---|---|
static int abs(int a) | 返回 a 的絕對值 |
static long abs(long a) | 返回 a 的絕對值 |
static float abs(float a) | 返回 a 的絕對值 |
static double abs(double a) | 返回 a 的絕對值 |
static int max(int x,int y) | 返回 x 和 y 中的最大值 |
static double max(double x,double y) | 返回 x 和 y 中的最大值 |
static long max(long x,long y) | 返回 x 和 y 中的最大值 |
static float max(float x,float y) | 返回 x 和 y 中的最大值 |
static int min(int x,int y) | 返回 x 和 y 中的最小值 |
static long min(long x,long y) | 返回 x 和 y 中的最小值 |
static double min(double x,double y) | 返回 x 和 y 中的最小值 |
static float min(float x,float y) | 返回 x 和 y 中的最小值 |
例 :求 10 和 20 的較大值玩焰、15.6 和 15 的較小值由驹、-12 的絕對值,代碼如下:
public class Test02 {
public static void main(String[] args) {
System.out.println("10 和 20 的較大值:" + Math.max(10, 20));
System.out.println("15.6 和 15 的較小值:" + Math.min(15.6, 15));
System.out.println("-12 的絕對值:" + Math.abs(-12));
}
}
該程序的運行結(jié)果如下:
10和20的較大值:20
15.6和15的較小值:15.0
-12的絕對值:12
求整運算
Math 類的求整方法有很多昔园,詳細說明如表 2 所示蔓榄。
方法 | 說明 |
---|---|
static double ceil(double a) | 返回大于或等于 a 的最小整數(shù) |
static double floor(double a) | 返回小于或等于 a 的最大整數(shù) |
static double rint(double a) | 返回最接近 a 的整數(shù)值,如果有兩個同樣接近的整數(shù)默刚,則結(jié)果取偶數(shù) |
static int round(float a) | 將參數(shù)加上 1/2 后返回與參數(shù)最近的整數(shù) |
static long round(double a) | 將參數(shù)加上 1/2 后返回與參數(shù)最近的整數(shù)甥郑,然后強制轉(zhuǎn)換為長整型 |
例:下面的實例演示了 Math 類中取整函數(shù)方法的應(yīng)用:
import java.util.Scanner;
public class Test03 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.outprintln("請輸入一個數(shù)字:");
double num = input.nextDouble();
System.out.println("大于或等于 "+ num +" 的最小整數(shù):" + Math.ceil(num));
System.out.println("小于或等于 "+ num +" 的最大整數(shù):" + Math.floor(num));
System.out.println("將 "+ num +" 加上 0.5 之后最接近的整數(shù):" + Math.round(num));
System.out.println("最接近 "+num+" 的整數(shù):" + Math.rint(num));
}
}
執(zhí)行結(jié)果如下:
請輸入一個數(shù)字:
99.01
大于或等于 99.01 的最小整數(shù):100.0
小于或等于 99.01 的最大整數(shù):99.0
將 99.01 加上 0.5 之后最接近的整數(shù):100
最接近 99.01 的整數(shù):99.0
三角函數(shù)運算
Math 類中包含的三角函數(shù)方法及其說明如表所示。
方法 | 說明 |
---|---|
static double sin(double a) | 返回角的三角正弦值羡棵,參數(shù)以孤度為單位 |
static double cos(double a) | 返回角的三角余弦值壹若,參數(shù)以孤度為單位 |
static double asin(double a) | 返回一個值的反正弦值嗅钻,參數(shù)域在 [-1,1]皂冰,值域在 [-PI/2,PI/2] |
static double acos(double a) | 返回一個值的反余弦值店展,參數(shù)域在 [-1,1],值域在 [0.0,PI] |
static double tan(double a) | 返回角的三角正切值秃流,參數(shù)以弧度為單位 |
static double atan(double a) | 返回一個值的反正切值赂蕴,值域在 [-PI/2,PI/2] |
static double toDegrees(double angrad) | 將用孤度表示的角轉(zhuǎn)換為近似相等的用角度表示的角 |
staticdouble toRadians(double angdeg) | 將用角度表示的角轉(zhuǎn)換為近似相等的用弧度表示的角 |
在表 3 中,每個方法的參數(shù)和返回值都是 double 類型舶胀,參數(shù)以弧度代替角度來實現(xiàn)概说,其中 1 度等于 π/180 弧度,因此平角就是 π 弧度嚣伐。
例:計算 90 度的正弦值糖赔、0 度的余弦值、1 的反正切值轩端、120 度的弧度值放典,代碼如下:
public class Test04 {
public static void main(String[] args) {
System.out.println{"90 度的正弦值:" + Math.sin(Math.PI/2));
System.out.println("0 度的余弦值:" + Math.cos(0));
System.out.println("1 的反正切值:" + Math.atan(l));
System.out.println("120 度的弧度值:" + Math.toRadians(120.0));
}
}
在上述代碼中,因為 Math.sin() 中的參數(shù)的單位是弧度基茵,而 90 度表示的是角度奋构,因此需要將 90 度轉(zhuǎn)換為弧度,即 Math.PI/180*90拱层,故轉(zhuǎn)換后的弧度為 Math.PI/2弥臼,然后調(diào)用 Math 類中的 sin() 方法計算其正弦值。
該程序的運行結(jié)果如下:
90 度的正弦值:1.0
0 的余弦值:1.0
1 的反正切值:0.7853981633974483
120 度的弧度值:2.0943951023931953
指數(shù)運算
指數(shù)的運算包括求方根根灯、取對數(shù)及其求 n 次方的運算径缅。在 Math 類中定義的指數(shù)運算方法及其說明如表 4 所示。
方法 | 說明 |
---|---|
static double exp(double a) | 返回 e 的 a 次冪 |
static double pow(double a,double b) | 返回以 a 為底數(shù)箱吕,以 b 為指數(shù)的冪值 |
static double sqrt(double a) | 返回 a 的平方根 |
static double cbrt(double a) | 返回 a 的立方根 |
static double log(double a) | 返回 a 的自然對數(shù)芥驳,即 lna 的值 |
static double log10(double a) | 返回以 10 為底 a 的對數(shù) |
例:使用 Math 類中的方法實現(xiàn)指數(shù)的運算,main() 方法中的代碼如下:
public class Test05 {
public static void main(String[] args) {
System.out.println("4 的立方值:" + Math.pow(4, 3));
System.out.println("16 的平方根:" + Math.sqrt(16));
System.out.println("10 為底 2 的對數(shù):" + Math.log1O(2));
}
}
該程序的運行結(jié)果如下:
4 的立方值:64.0
16 的平方根:4.0
10 為底 2 的對數(shù):0.3010299956639812
生成隨機數(shù)
在 Java 中要生成一個指定范圍之內(nèi)的隨機數(shù)字有兩種方法:一種是調(diào)用 Math 類的 random() 方法茬高,一種是使用 Random 類兆旬。
Random 類提供了豐富的隨機數(shù)生成方法,可以產(chǎn)生 boolean怎栽、int丽猬、long、float熏瞄、byte 數(shù)組以及 double 類型的隨機數(shù)脚祟,這是它與 random() 方法最大的不同之處。random() 方法只能產(chǎn)生 double 類型的 0~1 的隨機數(shù)强饮。
Random 類位于 java.util 包中由桌,該類常用的有如下兩個構(gòu)造方法。
- Random():該構(gòu)造方法使用一個和當前系統(tǒng)時間對應(yīng)的數(shù)字作為種子數(shù),然后使用這個種子數(shù)構(gòu)造 Random 對象行您。
- Random(long seed):使用單個 long 類型的參數(shù)創(chuàng)建一個新的隨機數(shù)生成器铭乾。
Random 類提供的所有方法生成的隨機數(shù)字都是均勻分布的,也就是說區(qū)間內(nèi)部的數(shù)字生成的概率是均等的娃循,在表 1 中列出了 Random 類中常用的方法炕檩。
方法 | 說明 |
---|---|
boolean nextBoolean() | 生成一個隨機的 boolean 值,生成 true 和 false 的值概率相等 |
double nextDouble() | 生成一個隨機的 double 值捌斧,數(shù)值介于 [0,1.0)笛质,含 0 而不包含 1.0 |
int nextlnt() | 生成一個隨機的 int 值,該值介于 int 的區(qū)間捞蚂,也就是 -231~231-1妇押。如果 需要生成指定區(qū)間的 int 值,則需要進行一定的數(shù)學變換 |
int nextlnt(int n) | 生成一個隨機的 int 值姓迅,該值介于 [0,n)舆吮,包含 0 而不包含 n。如果想生成 指定區(qū)間的 int 值队贱,也需要進行一定的數(shù)學變換 |
void setSeed(long seed) | 重新設(shè)置 Random 對象中的種子數(shù)色冀。設(shè)置完種子數(shù)以后的 Random 對象 和相同種子數(shù)使用 new 關(guān)鍵字創(chuàng)建出的 Random 對象相同 |
long nextLong() | 返回一個隨機長整型數(shù)字 |
boolean nextBoolean() | 返回一個隨機布爾型值 |
float nextFloat() | 返回一個隨機浮點型數(shù)字 |
double nextDouble() | 返回一個隨機雙精度值 |
例 :下面編寫一個 Java 程序,演示如何使用 Random 類提供的方法來生成隨機數(shù)柱嫌。具體代碼如下:
import java.util.Random;
public class Test06 {
public static void main(String[] args) {
Random r = new Random();
double d1 = r.nextDouble(); // 生成[0,1.0]區(qū)間的小數(shù)
double d2 = r.nextDouble() * 7; // 生成[0,7.0]區(qū)間的小數(shù)
int i1 = r.nextInt(10); // 生成[0,10]區(qū)間的整數(shù)
int i2 = r.nextInt(18) - 3; // 生成[-3,15]區(qū)間的整數(shù)
long l1 = r.nextLong(); // 生成一個隨機長整型值
boolean b1 = r.nextBoolean(); // 生成一個隨機布爾型值
float f1 = r.nextFloat(); // 生成一個隨機浮點型值
System.out.println("生成的[0,1.0]區(qū)間的小數(shù)是:" + d1);
System.out.println("生成的[0,7.0]區(qū)間的小數(shù)是:" + d2);
System.out.println("生成的[0,10]區(qū)間的整數(shù)是:" + i1);
System.out.println("生成的[-3,15]區(qū)間的整數(shù)是:" + i2);
System.out.println("生成一個隨機長整型值:" + l1);
System.out.println("生成一個隨機布爾型值:" + b1);
System.out.println("生成一個隨機浮點型值:" + f1);
System.out.print("下期七星彩開獎號碼預(yù)測:");
for (int i = 1; i < 8; i++) {
int num = r.nextInt(9); // 生成[0,9]區(qū)間的整數(shù)
System.out.print(num);
}
}
}
本實例每次運行時結(jié)果都不相同锋恬,這就實現(xiàn)了隨機產(chǎn)生數(shù)據(jù)的功能。該程序的運行結(jié)果如下:
生成的[0,1.0]區(qū)間的小數(shù)是:0.8773165855918825
生成的[0,7.0]區(qū)間的小數(shù)是:6.407083074782282
生成的[0,10]區(qū)間的整數(shù)是:5
生成的[-3,15]區(qū)間的整數(shù)是:4
生成一個隨機長整型值:-8462847591661221914
生成一個隨機布爾型值:false
生成一個隨機浮點型值:0.6397003
下期七星彩開獎號碼預(yù)測:0227168
例:Math 類的 random() 方法沒有參數(shù)编丘,它默認會返回大于等于 0.0与学、小于 1.0 的 double 類型隨機數(shù),即 0<=隨機數(shù)<1.0嘉抓。對 random() 方法返回的數(shù)字稍加處理索守,即可實現(xiàn)產(chǎn)生任意范圍隨機數(shù)的功能。
下面使用 random() 方法實現(xiàn)隨機生成一個 2~100 偶數(shù)的功能抑片。具體代碼如下:
public class Test07 {
public static void main(String[] args) {
int min = 2; // 定義隨機數(shù)的最小值
int max = 102; // 定義隨機數(shù)的最大值
// 產(chǎn)生一個2~100的數(shù)
int s = (int) min + (int) (Math.random() * (max - min));
if (s % 2 == 0) {
// 如果是偶數(shù)就輸出
System.out.println("隨機數(shù)是:" + s);
} else {
// 如果是奇數(shù)就加1后輸出
System.out.println("隨機數(shù)是:" + (s + 1));
}
}
}
由于 m+(int)(Math.random()n) 語句可以獲取 m~m+n 的隨機數(shù)卵佛,所以 2+(int)(Math. random()(102-2)) 表達式可以求出 2~100 的隨機數(shù)。在產(chǎn)生這個區(qū)間的隨機數(shù)后還需要判斷是否為偶數(shù)敞斋,這里使用了對 2 取余數(shù)截汪,如果余數(shù)不是零,說明隨機數(shù)是奇數(shù)植捎,此時將隨機數(shù)加 1 后再輸出衙解。
該程序的運行結(jié)果如下:
隨機數(shù)是:20
數(shù)字格式化
數(shù)字的格式在解決實際問題時使用非常普遍,這時可以使用 DedmalFormat 類對結(jié)果進行格式化處理焰枢。例如蚓峦,將小數(shù)位統(tǒng)一成 2 位舌剂,不足 2 位的以 0 補齊。
DecimalFormat 是 NumberFormat 的一個子類暑椰,用于格式化十進制數(shù)字架诞。DecimalFormat 類包含一個模式和一組符號,常用符號的說明如表 1 所示干茉。
符號 | 說明 |
---|---|
0 | 顯示數(shù)字,如果位數(shù)不夠則補 0 |
# | 顯示數(shù)字很泊,如果位數(shù)不夠不發(fā)生變化 |
. | 小數(shù)分隔符 |
- | 減號 |
, | 組分隔符 |
E | 分隔科學記數(shù)法中的尾數(shù)和小數(shù) |
% | 前綴或后綴角虫,乘以 100 后作為百分比顯示 |
? | 乘以 1000 后作為千進制貨幣符顯示。用貨幣符號代替委造。如果雙寫戳鹅,用國際貨幣符號代替; 如果出現(xiàn)在一個模式中昏兆,用貨幣十進制分隔符代替十進制分隔符 |
例:下面編寫一個 Java 程序枫虏,演示如何使用 DecimalFormat 類將數(shù)字轉(zhuǎn)換成各種格式,實現(xiàn)代碼如下爬虱。
import java.text.DecimalFormat;
import java.util.Scanner;
public class Test08 {
public static void main(String[] args) {
// 實例化DecimalFormat類的對象隶债,并指定格式
DecimalFormat df1 = new DecimalFormat("0.0");
DecimalFormat df2 = new DecimalFormat("#.#");
DecimalFormat df3 = new DecimalFormat("000.000");
DecimalFormat df4 = new DecimalFormat("###.###");
Scanner scan = new Scanner(System.in);
System.out.print("請輸入一個float類型的數(shù)字:");
float f = scan.nextFloat();
// 對輸入的數(shù)字應(yīng)用格式,并輸出結(jié)果
System.out.println("0.0 格式:" + df1.format(f));
System.out.println("#.# 格式:" + df2.format(f));
System.out.println("000.000 格式:" + df3.format(f));
System.out.println("###.### 格式:" + df4.format(f));
}
}
執(zhí)行上述代碼跑筝,輸出結(jié)果如下所示:
請輸入一個float類型的數(shù)字:5487.45697
0.0 格式:5487.5
#.# 格式:5487.5
000.000 格式:5487.457
###.### 格式:5487.457
請輸入一個float類型的數(shù)字:5.0
0.0 格式:5.0
#.# 格式:5
000.000 格式:005.000
###.### 格式:5
大數(shù)字運算
在 Java 中提供了用于大數(shù)字運算的類死讹,即 java.math.BigInteger 類和 java.math.BigDecimal 類。這兩個類用于高精度計算曲梗,其中 BigInteger 類是針對整型大數(shù)字的處理類赞警,而 BigDecimal 類是針對大小數(shù)的處理類。
BigInteger 類
如果要存儲比 Integer 更大的數(shù)字虏两,Integer 數(shù)據(jù)類型就無能為力了愧旦。因此,Java 中提供 BigInteger 類來處理更大的數(shù)字定罢。
BigInteger 類型的數(shù)字范圍較 Integer 類型的數(shù)字范圍要大得多笤虫。BigInteger 支持任意精度的整數(shù),也就是說在運算中 BigInteger 類型可以準確地表示任何大小的整數(shù)值祖凫。
除了基本的加耕皮、減、乘蝙场、除操作之外凌停,BigInteger 類還封裝了很多操作,像求絕對值售滤、相反數(shù)罚拟、最大公約數(shù)以及判斷是否為質(zhì)數(shù)等台诗。
要使用 BigInteger 類,首先要創(chuàng)建一個 BigInteger 對象赐俗。BigInteger 類提供了很多種構(gòu)造方法拉队,其中最直接的一種是參數(shù)以字符串形式代表要處理的數(shù)字。這個方法語法格式如下:
BigInteger(String val)
這里的 val 是數(shù)字十進制的字符串阻逮。例如粱快,要將數(shù)字 5 轉(zhuǎn)換為 BigInteger 對象,語句如下:
BigInteger bi = new BigInteger("5")
注意:這里數(shù)字 5 的雙引號是必需的叔扼,因為 BigInteger 類構(gòu)造方法要求參數(shù)是字符串類型事哭。
創(chuàng)建 BigInteger 對象之后,便可以調(diào)用 BigInteger 類提供的方法進行各種數(shù)學運算操作瓜富,表 1 列出了 BigInteger 類的常用運算方法鳍咱。
方法名稱 | 說明 |
---|---|
add(BigInteger val) | 做加法運算 |
subtract(BigInteger val) | 做減法運算 |
multiply(BigInteger val) | 做乘法運算 |
divide(BigInteger val) | 做除法運算 |
remainder(BigInteger val) | 做取余數(shù)運算 |
divideAndRemainder(BigInteger val) | 做除法運算,返回數(shù)組的第一個值為商与柑,第二個值為余數(shù) |
pow(int exponent) | 做參數(shù)的 exponent 次方運算 |
negate() | 取相反數(shù) |
shiftLeft(int n) | 將數(shù)字左移 n 位谤辜,如果 n 為負數(shù),則做右移操作 |
shiftRight(int n) | 將數(shù)字右移 n 位价捧,如果 n 為負數(shù)丑念,則做左移操作 |
and(BigInteger val) | 做與運算 |
or(BigInteger val) | 做或運算 |
compareTo(BigInteger val) | 做數(shù)字的比較運算 |
equals(Object obj) | 當參數(shù) obj 是 Biglnteger 類型的數(shù)字并且數(shù)值相等時返回 true, 其他返回 false |
min(BigInteger val) | 返回較小的數(shù)值 |
max(BigInteger val) | 返回較大的數(shù)值 |
BigDecimal 類
BigInteger 和 BigDecimal 都能實現(xiàn)大數(shù)字的運算,不同的是 BigDecimal 加入了小數(shù)的概念结蟋。一般的 float 和 double 類型數(shù)據(jù)只能用來做科學計算或工程計算渠欺,但由于在商業(yè)計算中要求數(shù)字精度比較高,所以要用到 BigDecimal 類椎眯。BigDecimal 類支持任何精度的浮點數(shù)挠将,可以用來精確計算貨幣值。
BigDecimal 常用的構(gòu)造方法如下编整。
- BigDecimal(double val):實例化時將雙精度型轉(zhuǎn)換為 BigDecimal 類型舔稀。
- BigDecimal(String val):實例化時將字符串形式轉(zhuǎn)換為 BigDecimal 類型。
BigDecimal 類的方法可以用來做超大浮點數(shù)的運算掌测,像加内贮、減、乘和除等汞斧。在所有運算中夜郁,除法運算是最復(fù)雜的,因為在除不盡的情況下粘勒,末位小數(shù)的處理方式是需要考慮的竞端。
下面列出了 BigDecimal 類用于實現(xiàn)加、減庙睡、乘和除運算的方法事富。
BigDecimal add(BigDecimal augend) // 加法操作
BigDecimal subtract(BigDecimal subtrahend) // 減法操作
BigDecimal multiply(BigDecimal multiplieand) // 乘法操作
BigDecimal divide(BigDecimal divisor,int scale,int roundingMode ) // 除法操作
其中技俐,divide() 方法的 3 個參數(shù)分別表示除數(shù)、商的小數(shù)點后的位數(shù)和近似值處理模式统台。
表列出了 roundingMode 參數(shù)支持的處理模式雕擂。
模式名稱 | 說明 |
---|---|
BigDecimal.ROUND_UP | 商的最后一位如果大于 0,則向前進位贱勃,正負數(shù)都如此 |
BigDecimal.ROUND_DOWN | 商的最后一位無論是什么數(shù)字都省略 |
BigDecimal.ROUND_CEILING | 商如果是正數(shù)井赌,按照 ROUND_UP 模式處理;如果是負數(shù)贵扰,按照 ROUND_DOWN 模式處理 |
BigDecimal.ROUND_FLOOR | 與 ROUND_CELING 模式相反仇穗,商如果是正數(shù),按照 ROUND_DOWN 模式處理拔鹰; 如果是負數(shù),按照 ROUND_UP 模式處理 |
BigDecimal.ROUND_HALF_ DOWN | 對商進行五舍六入操作贵涵。如果商最后一位小于等于 5列肢,則做舍棄操作,否則對最后 一位進行進位操作 |
BigDecimal.ROUND_HALF_UP | 對商進行四舍五入操作宾茂。如果商最后一位小于 5瓷马,則做舍棄操作,否則對最后一位 進行進位操作 |
BigDecimal.ROUND_HALF_EVEN | 如果商的倒數(shù)第二位是奇數(shù)跨晴,則按照 ROUND_HALF_UP 處理欧聘;如果是偶數(shù),則按 照 ROUND_HALF_DOWN 處理 |
日期&時間處理
在 Java 中獲取當前時間端盆,可以使用 java.util.Date 類和 java.util.Calendar 類完成怀骤。其中,Date 類主要封裝了系統(tǒng)的日期和時間的信息焕妙,Calendar 類則會根據(jù)系統(tǒng)的日歷來解釋 Date 對象蒋伦。
Date 類
Date 類表示系統(tǒng)特定的時間戳,可以精確到毫秒焚鹊。Date 對象表示時間的默認順序是星期痕届、月、日末患、小時研叫、分、秒璧针、年嚷炉。
構(gòu)造方法
Date 類有如下兩個構(gòu)造方法。
- Date():此種形式表示分配 Date 對象并初始化此對象探橱,以表示分配它的時間(精確到毫秒)渤昌,使用該構(gòu)造方法創(chuàng)建的對象可以獲取本地的當前時間虽抄。
- Date(long date):此種形式表示從 GMT 時間(格林尼治時間)1970 年 1 月 1 日 0 時 0 分 0 秒開始經(jīng)過參數(shù) date 指定的毫秒數(shù)。
這兩個構(gòu)造方法的使用示例如下:
Date date1 = new Date(); // 調(diào)用無參數(shù)構(gòu)造函數(shù)
System.out.println(date1.toString()); // 輸出:Wed May 18 21:24:40 CST 2016
Date date2 = new Date(60000); // 調(diào)用含有一個long類型參數(shù)的構(gòu)造函數(shù)
System.out.println(date2); // 輸出:Thu Jan 0108:01:00 CST 1970
Date 類的無參數(shù)構(gòu)造方法獲取的是系統(tǒng)當前的時間独柑,顯示的順序為星期迈窟、月、日忌栅、小時车酣、分、秒索绪、年湖员。
Date 類帶 long 類型參數(shù)的構(gòu)造方法獲取的是距離 GMT 指定毫秒數(shù)的時間,60000 毫秒是一分鐘瑞驱,而 GMT(格林尼治標準時間)與 CST(中央標準時間)相差 8 小時娘摔,也就是說 1970 年 1 月 1 日 00:00:00 GMT 與 1970 年 1 月 1 日 08:00:00 CST 表示的是同一時間。 因此距離 1970 年 1 月 1 日 00:00:00 CST 一分鐘的時間為 1970 年 1 月 1 日 00:01:00 CST唤反,即使用 Date 對象表示為 Thu Jan 01 08:01:00 CST 1970凳寺。
常用方法
Date 類提供了許多與日期和事件相關(guān)的方法,其中常見的方法如表所示彤侍。
方法 | 描述 |
---|---|
boolean after(Date when) | 判斷此日期是否在指定日期之后 |
boolean before(Date when) | 判斷此日期是否在指定日期之前 |
int compareTo(Date anotherDate) | 比較兩個日期的順序 |
boolean equals(Object obj) | 比較兩個日期的相等性 |
long getTime() | 返回自 1970 年 1 月 1 日 00:00:00 GMT 以來肠缨,此 Date 對象表示的毫秒數(shù) |
String toString() | 把此 Date 對象轉(zhuǎn)換為以下形式的 String: dow mon dd hh:mm:ss zzz yyyy。 其中 dow 是一周中的某一天(Sun盏阶、Mon晒奕、Tue、Wed名斟、Thu脑慧、Fri 及 Sat) |
例:下面使用一個實例來具體演示 Date 類的使用。假設(shè)砰盐,某一天特定時間要去做一件事漾橙,而且那個時間已經(jīng)過去一分鐘之后才想起來這件事還沒有辦,這時系統(tǒng)將會提示已經(jīng)過去了多 長時間楞卡。具體的代碼如下:
import java.util.Date;
import java.util.Scanner;
public class Test11 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("請輸入要做的事情:");
String title = input.next();
Date date1 = new Date(); // 獲取當前日期
System.out.println("[" + title + "] 這件事發(fā)生時間為:" + date1);
try {
Thread.sleep(60000);// 暫停 1 分鐘
} catch (InterruptedException e) {
e.printStackTrace();
}
Date date2 = new Date();
System.out.println("現(xiàn)在時間為:" + date2);
if (date2.before(date1)) {
System.out.println("你還有 " + (date2.getTime() - date1.getTime()) / 1000 + " 秒需要去完成【" + title + "】這件事霜运!");
} else {
System.out.println("【" + title + "】事情已經(jīng)過去了 " + (date2.getTime() - date1.getTime()) / 1000 + " 秒");
}
}
}
在該程序中,分別使用 Date 類的無參數(shù)構(gòu)造方法創(chuàng)建了兩個 Date 對象蒋腮。在創(chuàng)建完第一個 Date 對象后淘捡,使用 Thread.sleep() 方法讓程序休眠 60 秒,然后再創(chuàng)建第二個 Date 對象池摧,這樣第二個 Date 對象所表示的時間將會在第一個 Date 對象所表示時間之后焦除,因此“date2.before(date1)”條件表達式不成立瞪慧,從而執(zhí)行 else 塊中的代碼忘古,表示事情已經(jīng)發(fā)生過。
運行該程序,執(zhí)行結(jié)果如下所示牙捉。
請輸入要做的事情:
收快遞
【收快遞】這件事發(fā)生時間為:Fri Oct 12 11:11:07 CST 2018
現(xiàn)在時間為:Fri Oct 12 11:12:07 CST 2018
【收快遞】事情已經(jīng)過去了 60 秒
Calendar 類
Calendar 類是一個抽象類娇掏,它為特定瞬間與 YEAR创肥、MONTH唠叛、DAY_OF—MONTH、HOUR 等日歷字段之間的轉(zhuǎn)換提供了一些方法灿渴,并為操作日歷字段(如獲得下星期的日期) 提供了一些方法洛波。
創(chuàng)建 Calendar 對象不能使用 new 關(guān)鍵字,因為 Calendar 類是一個抽象類骚露,但是它提供了一個 getInstance() 方法來獲得 Calendar類的對象蹬挤。getInstance() 方法返回一個 Calendar 對象,其日歷字段已由當前日期和時間初始化棘幸。
Calendar c = Calendar.getInstance();
當創(chuàng)建了一個 Calendar 對象后焰扳,就可以通過 Calendar 對象中的一些方法來處理日期、時間误续。Calendar 類的常用方法如表 所示吨悍。
方法 | 描述 |
---|---|
void add(int field, int amount) | 根據(jù)日歷的規(guī)則,為給定的日歷字段 field 添加或減去指定的時間量 amount |
boolean after(Object when) | 判斷此 Calendar 表示的時間是否在指定時間 when 之后女嘲,并返回判斷結(jié)果 |
boolean before(Object when) | 判斷此 Calendar 表示的時間是否在指定時間 when 之前畜份,并返回判斷結(jié)果 |
void clear() | 清空 Calendar 中的日期時間值 |
int compareTo(Calendar anotherCalendar) | 比較兩個 Calendar 對象表示的時間值(從格林威治時間 1970 年 01 月 01 日 00 時 00 分 00 秒至現(xiàn)在的毫秒偏移量)诞帐,大則返回 1欣尼,小則返回 -1,相等返回 0 |
int get(int field) | 返回指定日歷字段的值 |
int getActualMaximum(int field) | 返回指定日歷字段可能擁有的最大值 |
int getActualMinimum(int field) | 返回指定日歷字段可能擁有的最小值 |
int getFirstDayOfWeek() | 獲取一星期的第一天停蕉。根據(jù)不同的國家地區(qū)愕鼓,返回不同的值 |
static Calendar getInstance() | 使用默認時區(qū)和語言壞境獲得一個日歷 |
static Calendar getInstance(TimeZone zone) | 使用指定時區(qū)和默認語言環(huán)境獲得一個日歷 |
static Calendar getInstance(TimeZone zone, Locale aLocale) | 使用指定時區(qū)和語言環(huán)境獲得一個日歷 |
Date getTime() | 返回一個表示此 Calendar 時間值(從格林威治時間 1970 年 01 月 01 日 00 時 00 分 00 秒至現(xiàn)在的毫秒偏移量)的 Date 對象 |
long getTimeInMillis() | 返回此 Calendar 的時間值,以毫秒為單位 |
void set(int field, int value) | 為指定的日歷字段設(shè)置給定值 |
void set(int year, int month, int date) | 設(shè)置日歷字段 YEAR慧起、MONTH 和 DAY_OF_MONTH 的值 |
void set(int year, int month, int date, int hourOfDay, int minute, int second) | 設(shè)置字段 YEAR菇晃、MONTH、DAY_OF_MONTH蚓挤、HOUR磺送、 MINUTE 和 SECOND 的值 |
void setFirstDayOfWeek(int value) | 設(shè)置一星期的第一天是哪一天 |
void setTimeInMillis(long millis) | 用給定的 long 值設(shè)置此 Calendar 的當前時間值 |
Calendar 對象可以調(diào)用 set() 方法將日歷翻到任何一個時間,當參數(shù) year 取負數(shù)時表示公元前灿意。Calendar 對象調(diào)用 get() 方法可以獲取有關(guān)年估灿、月、日等時間信息缤剧,參數(shù) field 的有效值由 Calendar 靜態(tài)常量指定馅袁。
Calendar 類中定義了許多常量,分別表示不同的意義荒辕。
- Calendar.YEAR:年份汗销。
- Calendar.MONTH:月份犹褒。
- Calendar.DATE:日期。
- Calendar.DAY_OF_MONTH:日期弛针,和上面的字段意義完全相同叠骑。
- Calendar.HOUR:12小時制的小時。
- Calendar.HOUR_OF_DAY:24 小時制的小時钦奋。
- Calendar.MINUTE:分鐘座云。
- Calendar.SECOND:秒。
- Calendar.DAY_OF_WEEK:星期幾付材。
例如朦拖,要獲取當前月份可用如下代碼:
int month = Calendar.getInstance().get(Calendar.MONTH);
如果整型變量 month 的值是 0,表示當前日歷是在 1 月份厌衔;如果值是 11璧帝,則表示當前日歷在 12 月份。
日期格式化
格式化日期表示將日期/時間格式轉(zhuǎn)換為預(yù)先定義的日期/時間格式富寿。例如將日期“Fri May 18 15:46:24 CST2016” 格式轉(zhuǎn)換為 “2016-5-18 15:46:24 星期五”的格式睬隶。
在 Java 中,可以使用 DateFormat 類和 SimpleDateFormat 類來格式化日期页徐。
DateFormat 類
DateFormat 是日期/時間格式化子類的抽象類苏潜,它以與語言無關(guān)的方式格式化并解析日期或時間。日期/時間格式化子類(如 SimpleDateFormat)允許進行格式化(也就是日期→文本)变勇、解析(文本→日期)和標準化日期恤左。
在創(chuàng)建 DateFormat 對象時不能使用 new 關(guān)鍵字,而應(yīng)該使用 DateFormat 類中的靜態(tài)方法 getDateInstance()搀绣,示例代碼如下:
DateFormat df = DateFormat.getDatelnstance();
在創(chuàng)建了一個 DateFormat 對象后飞袋,可以調(diào)用該對象中的方法來對日期/時間進行格式化。DateFormat 類中常用方法如表所示链患。
方法 | 描述 |
---|---|
String format(Date date) | 將 Date 格式化日期/時間字符串 |
Calendar getCalendar() | 獲取與此日期/時間格式相關(guān)聯(lián)的日歷 |
static DateFormat getDateInstance() | 獲取具有默認格式化風格和默認語言環(huán)境的日期格式 |
static DateFormat getDateInstance(int style) | 獲取具有指定格式化風格和默認語言環(huán)境的日期格式 |
static DateFormat getDateInstance(int style, Locale locale) | 獲取具有指定格式化風格和指定語言環(huán)境的日期格式 |
static DateFormat getDateTimeInstance() | 獲取具有默認格式化風格和默認語言環(huán)境的日期/時間 格式 |
static DateFormat getDateTimeInstance(int dateStyle,int timeStyle) | 獲取具有指定日期/時間格式化風格和默認語言環(huán)境的 日期/時間格式 |
static DateFormat getDateTimeInstance(int dateStyle,int timeStyle,Locale locale) | 獲取具有指定日期/時間格式化風格和指定語言環(huán)境的 日期/時間格式 |
static DateFormat getTimeInstance() | 獲取具有默認格式化風格和默認語言環(huán)境的時間格式 |
static DateFormat getTimeInstance(int style) | 獲取具有指定格式化風格和默認語言環(huán)境的時間格式 |
static DateFormat getTimeInstance(int style, Locale locale) | 獲取具有指定格式化風格和指定語言環(huán)境的時間格式 |
void setCalendar(Calendar newCalendar) | 為此格式設(shè)置日歷 |
Date parse(String source) | 將給定的字符串解析成日期/時間 |
格式化樣式主要通過 DateFormat 常量設(shè)置巧鸭。將不同的常量傳入到表所示的方法中,以控制結(jié)果的長度麻捻。DateFormat 類的常量如下纲仍。
- SHORT:完全為數(shù)字,如 12.5.10 或 5:30pm贸毕。
- MEDIUM:較長郑叠,如 May 10,2016崖咨。
- LONG:更長锻拘,如 May 12,2016 或 11:15:32am。
- FULL:是完全指定署拟,如 Tuesday婉宰、May 10、2012 AD 或 11:l5:42am CST推穷。
使用 DateFormat 類格式化曰期/時間的示例如下:
// 獲取不同格式化風格和中國環(huán)境的日期
DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT, Locale.CHINA);
DateFormat df2 = DateFormat.getDateInstance(DateFormat.FULL, Locale.CHINA);
DateFormat df3 = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.CHINA);
DateFormat df4 = DateFormat.getDateInstance(DateFormat.LONG, Locale.CHINA);
// 獲取不同格式化風格和中國環(huán)境的時間
DateFormat df5 = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.CHINA);
DateFormat df6 = DateFormat.getTimeInstance(DateFormat.FULL, Locale.CHINA);
DateFormat df7 = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.CHINA);
DateFormat df8 = DateFormat.getTimeInstance(DateFormat.LONG, Locale.CHINA);
// 將不同格式化風格的日期格式化為日期字符串
String date1 = df1.format(new Date());
String date2 = df2.format(new Date());
String date3 = df3.format(new Date());
String date4 = df4.format(new Date());
// 將不同格式化風格的時間格式化為時間字符串
String time1 = df5.format(new Date());
String time2 = df6.format(new Date());
String time3 = df7.format(new Date());
String time4 = df8.format(new Date());
// 輸出日期
System.out.println("SHORT:" + date1 + " " + time1);
System.out.println("FULL:" + date2 + " " + time2);
System.out.println("MEDIUM:" + date3 + " " + time3);
System.out.println("LONG:" + date4 + " " + time4);
運行該段代碼心包,輸出的結(jié)果如下:
SHORT:18-10-15 上午9:30
FULL:2018年10月15日 星期一 上午09時30分43秒 CST
MEDIUM:2018-10-15 9:30:43
LONG:2018年10月15日 上午09時30分43秒
SimpleDateFormat 類
如果使用 DateFormat 類格式化日期/時間并不能滿足要求,那么就需要使用 DateFormat 類的子類——SimpleDateFormat馒铃。
SimpleDateFormat 是一個以與語言環(huán)境有關(guān)的方式來格式化和解析日期的具體類蟹腾,它允許進行格式化(日期→文本)、解析(文本→日期)和規(guī)范化区宇。SimpleDateFormat 使得可以選擇任何用戶定義的日期/時間格式的模式娃殖。
SimpleDateFormat 類主要有如下 3 種構(gòu)造方法。
- SimpleDateFormat():用默認的格式和默認的語言環(huán)境構(gòu)造 SimpleDateFormat议谷。
- SimpleDateFormat(String pattern):用指定的格式和默認的語言環(huán)境構(gòu)造 SimpleDateF ormat炉爆。
- SimpleDateFormat(String pattern,Locale locale):用指定的格式和指定的語言環(huán)境構(gòu)造 SimpleDateF ormat。
SimpleDateFormat 自定義格式中常用的字母及含義如表所示卧晓。
字母 | 含義 | 示例 |
---|---|---|
y | 年份芬首。一般用 yy 表示兩位年份,yyyy 表示 4 位年份 | 使用 yy 表示的年扮逼裆,如 11郁稍; 使用 yyyy 表示的年份,如 2011 |
M | 月份胜宇。一般用 MM 表示月份耀怜,如果使用 MMM,則會 根據(jù)語言環(huán)境顯示不同語言的月份 | 使用 MM 表示的月份掸屡,如 05封寞; 使用 MMM 表示月份然评,在 Locale.CHINA 語言環(huán)境下仅财,如“十月”;在 Locale.US 語言環(huán)境下碗淌,如 Oct |
d | 月份中的天數(shù)盏求。一般用 dd 表示天數(shù) | 使用 dd 表示的天數(shù),如 10 |
D | 年份中的天數(shù)亿眠。表示當天是當年的第幾天碎罚, 用 D 表示 | 使用 D 表示的年份中的天數(shù),如 295 |
E | 星期幾纳像。用 E 表示荆烈,會根據(jù)語言環(huán)境的不同, 顯示不 同語言的星期幾 | 使用 E 表示星期幾,在 Locale.CHINA 語 言環(huán)境下憔购,如“星期四”宫峦;在 Locale.US 語 言環(huán)境下,如 Thu |
H | 一天中的小時數(shù)(0~23)玫鸟。一般用 HH 表示小時數(shù) | 使用 HH 表示的小時數(shù)导绷,如 18 |
h | 一天中的小時數(shù)(1~12)。一般使用 hh 表示小時數(shù) | 使用 hh 表示的小時數(shù)屎飘,如 10 (注意 10 有 可能是 10 點妥曲,也可能是 22 點) |
m | 分鐘數(shù)。一般使用 mm 表示分鐘數(shù) | 使用 mm 表示的分鐘數(shù)钦购,如 29 |
s | 秒數(shù)檐盟。一般使用 ss 表示秒數(shù) | 使用 ss 表示的秒數(shù),如 38 |
S | 毫秒數(shù)押桃。一般使用 SSS 表示毫秒數(shù) | 使用 SSS 表示的毫秒數(shù)遵堵,如 156 |
例 :編寫 Java 程序,使用 SimpleDateFormat 類格式化當前日期并打印怨规,日期格式為“xxxx 年 xx 月 xx 日星期 xxx 點 xx 分 xx 秒”陌宿,具體的實現(xiàn)代碼如下:
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test13 {
public static void main(String[] args) {
Date now = new Date(); // 創(chuàng)建一個Date對象,獲取當前時間
// 指定格式化格式
SimpleDateFormat f = new SimpleDateFormat("今天是 " + "yyyy 年 MM 月 dd 日 E HH 點 mm 分 ss 秒");
System.out.println(f.format(now)); // 將當前時間袼式化為指定的格式
}
}
該程序的運行結(jié)果如下:
今天是 2018 年 10 月 15 日 星期一 09 點 26 分 23 秒