Java String類
在前面的Java 字符串小節(jié),我們就已經(jīng)接觸了String
類,但并未提及String
類相關(guān)的操作,現(xiàn)在有了面向?qū)ο笙嚓P(guān)前置知識(shí),我們知道了類下面可以有相關(guān)的操作,作為Java
語(yǔ)言的內(nèi)置類,String
類也為我們預(yù)先定義了很多好用的方法,本小節(jié)我們將介紹String
類的常用方法,并結(jié)合示例輔助理解。
1. String 對(duì)象的創(chuàng)建
String對(duì)象的創(chuàng)建有兩種方式。
第1 種方式就是我們最常見的創(chuàng)建字符串的方式:
String str1 = "Hello, 慕課網(wǎng)";
第 2 種方式是對(duì)象實(shí)例化的方式,使用new
關(guān)鍵字,并將要?jiǎng)?chuàng)建的字符串作為構(gòu)造參數(shù):
String str2 = new String("Hello, Java");
如果調(diào)用 String 類的無(wú)參構(gòu)造方法,則會(huì)創(chuàng)建一個(gè)空字符串:
String str3 = new String();
此處的str3
就是一個(gè)空字符串。但注意,這種方式很少使用。
2. 獲取字符串長(zhǎng)度
可以使用length()
方法來(lái)獲取字符串的長(zhǎng)度。例如:
public class StringMethod1 {
public static void main(String[] args) {
// 創(chuàng)建String對(duì)象str
String str = "hello world!";
// 調(diào)用對(duì)象下length()方法,并使用int類型變量接收返回結(jié)果
int length = str.length();
System.out.println("str的長(zhǎng)度為:" + length);
}
}
運(yùn)行結(jié)果:
str1的長(zhǎng)度為:12
注意,hello world!
中的空格也算一個(gè)字符。
3. 字符串查找
3.1 獲取指定位置字符
可以使用char charAt(int index)
方法獲取字符串指定位置的字符。它接收一個(gè)整型的index
參數(shù),指的是索引位置,那什么是索引位置呢?例如,有一字符串I love Java
,其每個(gè)字符的索引如下圖所示:

可以從圖示中看出,索引下標(biāo)從0
開始。假如我們要獲取字符J
,則為方法傳入?yún)?shù)7
即可:
public class StringMethod2 {
public static void main(String[] args) {
String str = "I love Java";
char c = str.charAt(7);
System.out.println("索引位置為7的字符為:" + c);
}
}
運(yùn)行結(jié)果:
索引位置為7的字符為:J
3.2 查找字符串位置
這里介紹查找字符串位置的兩個(gè)方法:
indexOf()
獲取字符或子串在字符串中第一次出現(xiàn)的位置。lasIndexOf()
獲取字符或子串在字符串中最后一次出現(xiàn)的位置。
這里的子串指的就是字符串中的連續(xù)字符組成的子序列。例如,字符串
Hello
就是字符串Hello Java
的子串。
indexOf()
有多個(gè)重載方法,這里我們只演示其中最常用的兩個(gè)。
- 獲取字符在字符串中第一次出現(xiàn)的位置:
public class StringMethod2 {
public static void main(String[] args) {
String str = "I love Java, I love imooc!";
int i = str.indexOf('a');
System.out.println("字符a在字符串str第一次出現(xiàn)的位置為:" + i);
}
}
運(yùn)行結(jié)果:
字符a在字符串str第一次出現(xiàn)的位置為:8
- 獲取子串在字符串中第一次出現(xiàn)的位置:
public class StringDemo2 {
public static void main(String[] args) {
String str = "I love Java, I love imooc!";
int i = str.indexOf("love");
System.out.println("子串love在字符串str第一次出現(xiàn)的位置為:" + i);
}
}
運(yùn)行結(jié)果:
子串love在字符串str第一次出現(xiàn)的位置為:2
關(guān)于lastIndexOf()
,我們也只演示最常用的兩個(gè)重載方法。
- 獲取字符在字符串中最后一次出現(xiàn)的位置:
public class StringMethod2 {
public static void main(String[] args) {
String str = "I love Java, I love imooc!";
int i = str.lastIndexOf('e');
System.out.println("字符e在字符串str最后一次出現(xiàn)的位置為:" + i);
}
}
運(yùn)行結(jié)果:
字符e在字符串str最后一次出現(xiàn)的位置為:18
- 獲取子串在字符串中最后一次出現(xiàn)的位置:
public class StringMethod2 {
public static void main(String[] args) {
String str = "I love Java, I love imooc!";
int i = str.lastIndexOf("I love");
System.out.println("字串I love在字符串str最后一次出現(xiàn)的位置為:" + i);
}
}
運(yùn)行結(jié)果:
字串I love在字符串str最后一次出現(xiàn)的位置為:13
需要特別注意的是,以上方法的參數(shù)都是區(qū)分大小寫的。這也就意味著,你永遠(yuǎn)無(wú)法在I love Java
中查找到字符E
。如果沒有查找,上述方法都會(huì)返回一個(gè)整型值:-1
。我們來(lái)看以下示例:
public class StringMethod2 {
public static void main(String[] args) {
String str = "I love Java";
int i = str.indexOf('E');
System.out.println(i);
}
}
運(yùn)行結(jié)果:
-1
4. 字符串截取
字符串的截取也稱為獲取子串,在實(shí)際開發(fā)中經(jīng)常用到,可以使用substring()
方法來(lái)獲取子串,String類中有兩個(gè)重載的實(shí)例方法:
String substring(int beginIndex)
獲取從beginIndex
位置開始到結(jié)束的子串。String substring(int beginIndex, int endIndex)
獲取從beginIndex
位置開始到endIndex
位置的子串(不包含endIndex
位置字符)。
關(guān)于這兩個(gè)方法的使用,我們來(lái)看一個(gè)實(shí)例:
public class StringMethod3 {
public static void main(String[] args) {
String str = "I love Java";
String substring = str.substring(2);
String substring1 = str.substring(2, 6);
System.out.println("從索引位置2到結(jié)束的子串為:" + substring);
System.out.println("從索引位置2到索引位置6的子串為:" + substring1);
}
}
運(yùn)行結(jié)果:
從索引位置2到結(jié)束的子串為:love Java
從索引位置2到索引位置6的子串為:love
要特別注意,方法簽名上有兩個(gè)參數(shù)的substring(int beginIndex, int endIndex)
方法,截取的子串不包含endIndex
位置的字符。
5. 字符串切割
5.1 切割為字串?dāng)?shù)組
String[] split(String regex)
方法可將字符串切割為子串,其參數(shù)regex
是一個(gè)正則表達(dá)式分隔符,返回字符串?dāng)?shù)組。例如,我們使用空格作為分隔符來(lái)切割I love Java
字符串,結(jié)果將返回含有3個(gè)元素的字符串?dāng)?shù)組:
public class StringMethod4 {
public static void main(String[] args) {
String str1 = "I love Java";
// 將字符串str1以空格分隔,并將分割結(jié)果賦值給strArr數(shù)組
String[] strArr = str1.split(" ");
// 遍歷數(shù)組,打印每一個(gè)元素
for (String str: strArr) {
System.out.print(str + '\t');
}
}
}
運(yùn)行結(jié)果:
I love Java
注意,有幾種特殊的分隔符:*
^
:
|
.
\
,要使用轉(zhuǎn)義字符轉(zhuǎn)義。例如:
// 以*切割
String str2 = "I*love*Java";
String[] strArr2 = str2.split("\\*");
// 以\切割
String str3 = "I\\love\\Java";
String[] strArr4 = str3.split("\\\\");
// 以|切割
String str4 = "I|love|Java";
String[] strArr4 = str4.split("\\|");
另外,還有一個(gè)重載方法String[] split(String regex, int limit)
,其第二個(gè)參數(shù)limit
用以控制正則匹配被應(yīng)用的次數(shù),因此會(huì)影響結(jié)果的長(zhǎng)度,此處不再一一舉例介紹。
5.2 切割為 byte 數(shù)組
在實(shí)際工作中,網(wǎng)絡(luò)上的數(shù)據(jù)傳輸就是使用二進(jìn)制字節(jié)數(shù)據(jù)。因此字符串和字節(jié)數(shù)組之間的相互轉(zhuǎn)換也很常用。
我們可以使用getBytes()
方法將字符串轉(zhuǎn)換為byte
數(shù)組。例如:
public class StringMethod4 {
public static void main(String[] args) {
String str2 = "我喜歡Java";
System.out.println("將字符串轉(zhuǎn)換為byte數(shù)組:");
// 將字符串轉(zhuǎn)換為字節(jié)數(shù)組
byte[] ascii = str2.getBytes();
// 遍歷字節(jié)數(shù)組,打印每個(gè)元素
for (byte aByte : ascii) {
System.out.print(aByte + "\t");
}
}
}
運(yùn)行結(jié)果:
將字符串轉(zhuǎn)換為byte數(shù)組:
-26 -120 -111 -27 -106 -100 -26 -84 -94 74 97 118 97
將字節(jié)數(shù)組轉(zhuǎn)換為字符串的方法很簡(jiǎn)單,直接實(shí)例化一個(gè)字符串對(duì)象,將字節(jié)數(shù)組作為構(gòu)造方法的參數(shù)即可:
// 此處的ascii為上面通過(guò)字符串轉(zhuǎn)換的字節(jié)數(shù)組
String s = new String(ascii);
6. 字符串大小寫轉(zhuǎn)換
字符串的大小寫轉(zhuǎn)換有兩個(gè)方法:
-
toLowerCase()
將字符串轉(zhuǎn)換為小寫 -
toUpperCase()
將字符串轉(zhuǎn)換為大寫
我們來(lái)看一個(gè)實(shí)例:
public class StringMethod5 {
public static void main(String[] args) {
String str = "HELLO world";
String s = str.toLowerCase();
System.out.println("字符串str為轉(zhuǎn)換為小寫后為:" + s);
String s1 = s.toUpperCase();
System.out.println("字符串s為轉(zhuǎn)換為大寫后為:" + s1);
}
}
運(yùn)行結(jié)果:
字符串str為轉(zhuǎn)換為小寫后為:hello world
字符串s為轉(zhuǎn)換為大寫后為:HELLO WORLD
試想,如果想把字符串HELLO world
中的大小寫字母互換,該如何實(shí)現(xiàn)呢?
這里可以結(jié)合字符串切割方法以及字符串連接來(lái)實(shí)現(xiàn):
public class StringMethod5 {
public static void main(String[] args) {
String str = "HELLO world";
// 先切割為數(shù)組
String[] strArr = str.split(" ");
// 將數(shù)組中元素轉(zhuǎn)換大小寫并連接為一個(gè)新的字符串
String result = strArr[0].toLowerCase() + " " + strArr[1].toUpperCase();
System.out.println("字符串str的大小寫互換后為:" + result);
}
}
運(yùn)行結(jié)果:
字符串str的大小寫互換后為:hello WORLD
當(dāng)然,實(shí)現(xiàn)方式不止一種,你可以結(jié)合所學(xué)寫出更多的方式。
7. 字符串比較
String
類提供了boolean equals(Object object)
方法來(lái)比較字符串內(nèi)容是否相同,返回一個(gè)布爾類型的結(jié)果。
需要特別注意的是,在比較字符串內(nèi)容是否相同時(shí),必須使用equals()
方法而不能使用==
運(yùn)算符。我們來(lái)看一個(gè)示例:
public class StringMethod6 {
public static void main(String[] args) {
// 用兩種方法創(chuàng)建三個(gè)內(nèi)容相同的字符串
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
System.out.println("使用equals()方法比較str1和str2的結(jié)果為:" + str1.equals(str2));
System.out.println("使用==運(yùn)算符比較str1和str2的結(jié)果為:" + (str1 == str2));
System.out.println("使用equals()方法比較str1和str3的結(jié)果為:" + str1.equals(str3));
System.out.println("使用==運(yùn)算符比較str1和str3的結(jié)果為:" + (str1 == str3));
}
}
運(yùn)行結(jié)果:
使用equals()方法比較str1和str2的結(jié)果為:true
使用==運(yùn)算符比較str1和str2的結(jié)果為:true
使用equals()方法比較str1和str3的結(jié)果為:true
使用==運(yùn)算符比較str1和str3的結(jié)果為:false
代碼中三個(gè)字符串str1
,str2
和str3
的內(nèi)容都是hello
,因此使用equals()
方法對(duì)它們進(jìn)行比較,其結(jié)果總是為true
。
注意觀察執(zhí)行結(jié)果,其中使用==
運(yùn)算符比較str1
和str2
的結(jié)果為true
,但使用==
運(yùn)算符比較的str1
和str3
的結(jié)果為false
。這是因?yàn)?code>==運(yùn)算符比較的是兩個(gè)變量的地址而不是內(nèi)容。
要探究其原因,就要理解上述創(chuàng)建字符串的代碼在計(jì)算機(jī)內(nèi)存中是如何執(zhí)行的。下面我們通過(guò)圖解的形式來(lái)描述這三個(gè)變量是如何在內(nèi)存中創(chuàng)建的。
- 當(dāng)執(zhí)行
String str1 = "hello;"
語(yǔ)句時(shí),會(huì)在內(nèi)存的??臻g中創(chuàng)建一個(gè)str1
,在常量池中創(chuàng)建一個(gè)"hello",并將str1
指向hello
。

- 當(dāng)執(zhí)行
String str2 = "hello";
語(yǔ)句時(shí),??臻g中會(huì)創(chuàng)建一個(gè)str2
,由于其內(nèi)容與str1
相同,會(huì)指向常量池中的同一個(gè)對(duì)象。所以str1
與str2
指向的地址是相同的,這就是==
運(yùn)算符比較str1
和str2
的結(jié)果為true
的原因。

- 當(dāng)執(zhí)行
String str3 = new String("hello");
語(yǔ)句時(shí),使用了new
關(guān)鍵字創(chuàng)建字符串對(duì)象,由于對(duì)象的實(shí)例化操作是在內(nèi)存的堆空間進(jìn)行的,此時(shí)會(huì)在??臻g創(chuàng)建一個(gè)str3
,在堆空間實(shí)例化一個(gè)內(nèi)容為hello
的字符串對(duì)象,并將str3
地址指向堆空間中的hello
,這就是==
運(yùn)算符比較str1
和str3
的結(jié)果為false
的原因。

8. 小結(jié)
本小節(jié)我們介紹了 Java String
類的常用方法:
- 使用
length()
方法可以獲取字符串長(zhǎng)度; - 使用
charAt()
、indexOf()
以及lastIndexOf()
方法可以對(duì)字符串進(jìn)行查找; substring()
方法可以對(duì)字符串的進(jìn)行截取,split()
、getBytes()
方法可以將字符串切割為數(shù)組;toLowerCase()
和toUpperCase()
方法分別用于大小寫轉(zhuǎn)換,使用equals()
方法對(duì)字符串進(jìn)行比較,這里要注意,對(duì)字符串內(nèi)容進(jìn)行比較時(shí),永遠(yuǎn)都不要使用==
運(yùn)算符。
這些方法大多有重載方法,實(shí)際工作中,要根據(jù)合適的場(chǎng)景選用對(duì)應(yīng)的重載方法。
當(dāng)然,本小節(jié)還有很多未介紹到的方法,使用到可以翻閱官網(wǎng)文檔來(lái)進(jìn)行學(xué)習(xí)。