一、 String類
1. String類概述
查閱API中的String類的描述们颜,發(fā)現(xiàn)String 類代表字符串吕朵。Java 程序中的所有字符串字面值(如 "abc" )都作為此類的實例實現(xiàn)。
繼續(xù)查閱API發(fā)現(xiàn)說字符串是常量窥突;它們的值在創(chuàng)建之后不能更改努溃,這是什么意思呢?其實就是說一旦這個字符串確定了阻问,那么就會在內(nèi)存區(qū)域的常量池中就生成了這個字符串梧税。字符串本身不能改變,但str變量中記錄的地址值是可以改變的。
繼續(xù)閱讀API發(fā)現(xiàn)第队,因為 String 對象是不可變的哮塞,所以可以共享,這又是什么意思呢凳谦?其實就是說由于字符串一旦生成忆畅,在常量池中是不可變的,那么不管有多少個引用尸执,只要他們的引用的字符串相同家凯,即就是這些引用指向同一片內(nèi)存區(qū)域。
繼續(xù)查API發(fā)現(xiàn)如失,字符串有大量的重載的構(gòu)造方法绊诲。通過String類的構(gòu)造方法可以完成字符串對象的創(chuàng)建,那么岖常,通過使用雙引號的方式創(chuàng)建對象與new的方式創(chuàng)建對象驯镊,有什么不同呢?看如下程序與圖解:
String s3 = "abc";
String s4 = new String("abc");
System.out.println(s3==s4);//false
System.out.println(s3.equals(s4));//true,
//因為String重寫了equals方法竭鞍,建立了字符串自己的判斷相同的依據(jù)(通過字符串對象中的字符來判斷)
s3和s4的創(chuàng)建方式有什么不同呢板惑?
? s3創(chuàng)建,在內(nèi)存中只有一個對象偎快。這個對象在字符串常量池中
? s4創(chuàng)建冯乘,在內(nèi)存中有兩個對象兰绣。一個new的對象在堆中履肃,一個字符串本身對象谭胚,在字符串常量池中
2. String類構(gòu)造方法
構(gòu)造方法是用來完成String對象的創(chuàng)建哥牍,下圖中給出了一部分構(gòu)造方法需要在API中找到,并能夠使用下列構(gòu)造方法創(chuàng)建對象煞抬。
String s1 = new String(); //創(chuàng)建String對象泌类,字符串中沒有內(nèi)容
byte[] bys = new byte[]{97,98,99,100};
String s2 = new String(bys); // 創(chuàng)建String對象缅刽,把數(shù)組元素作為字符串的內(nèi)容
String s3 = new String(bys, 1, 3); //創(chuàng)建String對象读跷,把一部分數(shù)組元素作為字符串的內(nèi)容梗搅,參數(shù)offset為數(shù)組元素的起始索引位置,參數(shù)length為要幾個元素
char[] chs = new char[]{’a’,’b’,’c’,’d’,’e’};
String s4 = new String(chs); //創(chuàng)建String對象效览,把數(shù)組元素作為字符串的內(nèi)容
String s5 = new String(chs, 0, 3);//創(chuàng)建String對象无切,把一部分數(shù)組元素作為字符串的內(nèi)容,參數(shù)offset為數(shù)組元素的起始索引位置丐枉,參數(shù)count為要幾個元素
String s6 = new String(“abc”); //創(chuàng)建String對象哆键,字符串內(nèi)容為abc
3. String類的常用方法
將此字符串與指定的對象比較。當且僅當該參數(shù)不為 null瘦锹,并且是與此對象表示相同字符序列的 String 對象時籍嘹,結(jié)果才為 true闪盔。
split() 方法根據(jù)匹配給定的正則表達式來拆分字符串。
參數(shù)
regex -- 正則表達式分隔符辱士。
limit -- 分割的份數(shù)锭沟。
返回值
字符串數(shù)組。
注意: . 识补、 | 和 * 等轉(zhuǎn)義字符,必須得加 \辫红。
注意:多個分隔符凭涂,可以用 | 作為連字符。
語法
public String[] split(String regex, int limit)
實例:
public class Test {
public static void main(String args[]) {
String str = new String("Welcome-to-Runoob");
System.out.println("- 分隔符返回值 :" );
for (String retval: str.split("-")){
System.out.println(retval);
}
System.out.println("");
System.out.println("- 分隔符設置分割份數(shù)返回值 :" );
for (String retval: str.split("-", 2)){
System.out.println(retval);
}
System.out.println("");
String str2 = new String("www.runoob.com");
System.out.println("轉(zhuǎn)義字符返回值 :" );
for (String retval: str2.split("\\.", 3)){
System.out.println(retval);
}
System.out.println("");
String str3 = new String("acount=? and uu =? or n=?");
System.out.println("多個分隔符返回值 :" );
for (String retval: str3.split("and|or")){
System.out.println(retval);
}
}
}
以上程序執(zhí)行結(jié)果為:
分隔符返回值 :
Welcome
to
Runoob分隔符設置分割份數(shù)返回值 :
Welcome
to-Runoob轉(zhuǎn)義字符返回值 :
www
runoob
com多個分隔符返回值 :
acount=?
uu =?
n=?
按字典順序比較兩個字符串贴妻。該比較基于字符串中各個字符的 Unicode 值切油。按字典順序?qū)⒋?String
對象表示的字符序列與參數(shù)字符串所表示的字符序列進行比較。如果按字典順序此 String
對象位于參數(shù)字符串之前名惩,則比較結(jié)果為一個負整數(shù)澎胡。如果按字典順序此 String
對象位于參數(shù)字符串之后,則比較結(jié)果為一個正整數(shù)娩鹉。如果這兩個字符串相等攻谁,則結(jié)果為 0;compareTo
只在方法 [equals(Object)
] 返回 true
時才返回 0
弯予。
這是字典排序的定義戚宦。如果這兩個字符串不同,那么它們要么在某個索引處的字符不同(該索引對二者均為有效索引)锈嫩,要么長度不同受楼,或者同時具備這兩種情況。如果它們在一個或多個索引位置上的字符不同呼寸,假設 k 是這類索引的最小值艳汽;則在位置 k 上具有較小值的那個字符串(使用 < 運算符確定),其字典順序在其他字符串之前对雪。在這種情況下河狐,compareTo
返回這兩個字符串在位置 k
處兩個char 值的差,即值:
this.charAt(k)-anotherString.charAt(k)
如果沒有字符不同的索引位置慌植,則較短字符串的字典順序在較長字符串之前甚牲。在這種情況下,compareTo
返回這兩個字符串長度的差蝶柿,即值:
this.length()-anotherString.length()
實例:
import java.io.*;
public class Test {
public static void main(String args[]) {
String Str1 = new String("runoob");
try{
byte[] Str2 = Str1.getBytes(); //無參數(shù)表示使用默認字符集
System.out.println("返回值:" + Str2 );
Str2 = Str1.getBytes( "UTF-8" );
System.out.println("返回值:" + Str2 );
Str2 = Str1.getBytes( "ISO-8859-1" );
System.out.println("返回值:" + Str2 );
} catch ( UnsupportedEncodingException e){
System.out.println("不支持的字符集");
}
}
}
以上程序執(zhí)行結(jié)果為:
返回值:[B@7852e922
返回值:[B@4e25154f
返回值:[B@70dea4e
返回此字符串的哈希碼丈钙。String 對象的哈希碼根據(jù)以下公式計算:
s[0]31^(n-1) + s[1]31^(n-2) + ... + s[n-1]
使用 int 算法,這里 s[i] 是字符串的第 i 個字符交汤,n 是字符串的長度雏赦,^ 表示求冪劫笙。(空字符串的哈希值為 0。)
其他常用方法:
將其他類型變量轉(zhuǎn)換為String
char數(shù)組轉(zhuǎn)換為String字符串
字符串轉(zhuǎn)數(shù)組
二星岗、StringBuffer類
StringBuffer又稱為可變字符序列填大,它是一個類似于 String 的字符串緩沖區(qū),通過某些方法調(diào)用可以改變該序列的長度和內(nèi)容俏橘。
原來StringBuffer是個字符串的緩沖區(qū)允华,即就是它是一個容器,容器中可以裝很多字符串寥掐。并且能夠?qū)ζ渲械淖址M行各種操作靴寂。
可將字符串緩沖區(qū)安全地用于多個線程。StringBuffer 上的主要操作是 append 和 insert 方法召耘,可重載這些方法百炬,以接受任意類型的數(shù)據(jù)。每個方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串污它,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中剖踊。append 方法始終將這些字符添加到緩沖區(qū)的末端;而 insert 方法則在指定的點添加字符衫贬。
無論多少數(shù)據(jù)德澈,數(shù)據(jù)是什么類型都不重要,只要最終變成字符串就可以使用StringBuffer這個容器祥山。
實例:int[] arr = {34,12,89,68};將一個int[]中元素轉(zhuǎn)成字符串 格式 [34,12,89,68]
public static String toString_2(int[] arr) {
StringBuffer sb = new StringBuffer();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if(i!=arr.length-1){
sb.append(arr[i]+",");
}else{
sb.append(arr[i]+"]");
}
}
return sb.toString();
}
每個字符串緩沖區(qū)都有一定的容量(長度等于字符串長度+16圃验,只創(chuàng)建對象為16)。只要字符串緩沖區(qū)所包含的字符序列的長度沒有超出此容量缝呕,就無需分配新的內(nèi)部緩沖區(qū)數(shù)組澳窑。如果內(nèi)部緩沖區(qū)溢出,則此容量自動增大供常。從 JDK 5 開始摊聋,為該類補充了一個單個線程使用的等價類,即 [StringBuilder
]栈暇。與該類相比麻裁,通常應該優(yōu)先使用 StringBuilder 類,因為它支持所有相同的操作源祈,但由于它不執(zhí)行同步煎源,所以速度更快。
1. StringBuffer構(gòu)造方法摘要
2. StringBuffer的方法使用
代碼演示:
創(chuàng)建一個字符串緩沖區(qū)對象香缺。用于存儲數(shù)據(jù)手销。
StringBuffer sb = new StringBuffer();
sb.append("haha"); //添加字符串
sb.insert(2, "it");//在指定位置插入
sb.delete(1, 4);//刪除
sb.replace(1, 4, "cast");//替換指定范圍內(nèi)的內(nèi)容
String str = sb.toString();
注意:append、delete图张、insert锋拖、replace诈悍、reverse方法調(diào)用后,返回值都是當前對象自己兽埃,所以說侥钳,StringBuffer它可以改變字符序列的長度和內(nèi)容。
stringbuffer的其他方法
3. 對象的方法鏈式調(diào)用
在我們開發(fā)中柄错,會遇到調(diào)用一個方法后舷夺,返回一個對象的情況。然后使用返回的對象繼續(xù)調(diào)用方法售貌。這種時候冕房,我們就可以把代碼現(xiàn)在一起,如append方法一樣趁矾,代碼如下:
創(chuàng)建一個字符串緩沖區(qū)對象。用于存儲數(shù)據(jù)给僵。
StringBuffer sb = new StringBuffer();
添加數(shù)據(jù)毫捣。不斷的添加數(shù)據(jù)后,要對緩沖區(qū)的最后的數(shù)據(jù)進行操作帝际,必須轉(zhuǎn)成字符串才可以蔓同。
String str = sb.append(true).append("hehe").toString();