操作字符串是計(jì)算機(jī)程序設(shè)計(jì)中最常見的行為,尤其是在web開發(fā)中。所以大家一定要掌握java中常見的字符串操作。并且要深入學(xué)習(xí)String類,因?yàn)镾tring是一個(gè)比較特別類。它有很多特性需要注意。
首先大家應(yīng)該知道字符串本質(zhì)是就是一個(gè)char類型的數(shù)組,例如 "Hello" 這個(gè)字符串就是由 'H'、'e'、'l'、'l'、'o' 這五個(gè)字符組成。在java中把這字符數(shù)組當(dāng)成String的一個(gè)實(shí)例??梢詫?duì)其進(jìn)行各種操作。

一些常規(guī)的操作我們就不多說了,大家可以自己去看java api,我們?cè)谶@兒說一下String的特性。和使用過程中的一下問題
不可變性
在學(xué)習(xí)使用java的時(shí)候,有一個(gè)非常重要的概念,那就是一旦一個(gè)String對(duì)象被創(chuàng)建,它就是不變的(immutable)。String類中每一個(gè)看起來是修改String值的方法。實(shí)際上都會(huì)創(chuàng)建一個(gè)新的String對(duì)象 看下面的代碼
/**
* 說明String的不可變性
* Created by wanghailong on 17/3/15.
*/
public class Immutable {
public static void main(String[] args) {
String q = "fighting";
System.out.println(q);
String qq = q.toUpperCase();
System.out.println(q);
System.out.println(qq);
}
}
我們看上面這個(gè)例子,我們可以看到對(duì)String值的操作,不會(huì)對(duì)原始值有任何影響,調(diào)用toUpperCase()方法后,其實(shí)是會(huì)創(chuàng)建一個(gè)新的對(duì)象。這其實(shí)也是我們想要的。我們也不希望調(diào)用之后改變?cè)瓉淼闹担蝗贿@個(gè)代碼的可讀性和維護(hù)成本就非常高了。
說到這兒,我們可以引起另外一個(gè)概念,就是在java執(zhí)行的時(shí)候,會(huì)維護(hù)一個(gè)String池,在創(chuàng)建一個(gè)字符串的時(shí)候,會(huì)先在String池中查找是否有相同的String內(nèi)容。如果有就直接返回。這會(huì)導(dǎo)致他們指向的是同一個(gè)字符串?dāng)?shù)組
String str1 = "flyweight";
String str2 = "flyweight";
System.out.println(str1 == str2);

如上圖所示
那么在這兒我問個(gè)問題:
String str1 = new String("caterpillar");
String str2 = new String("caterpillar");
System.out.println(str1 == str2);
這段代碼執(zhí)行會(huì)返回 true 嗎?答案不會(huì),為什么呢?原因是‘==’是用來比較變量是否指向同一個(gè)對(duì)象。她不是用來比較對(duì)象的內(nèi)容的,這一點(diǎn)大家要注意。兩個(gè)對(duì)象的內(nèi)容是否相等,只能通過equals()來個(gè)比較。這個(gè)我們就不在這兒展開講了。大家在做相等比較的時(shí)候,盡量還是使用equals()來比較
StringBuilder
在說StringBuilder的之前,我們先說一下“+”操作符在String中的意義,"+"和"+="對(duì)于String是特殊意義的,事實(shí)上,用于字符串操作的"+"和"+="是唯一被重載過的操作符。
public class StringAdd {
public static void main(String[] args) {
String mango = "test";
String s = "a"+"b"+"c"+mango;
System.out.println(s);
}
}
這個(gè)代碼的執(zhí)行邏輯是這樣的,先生成包含"a"的String對(duì)象,"a"+"b"又生成一個(gè)包含"ab"的對(duì)象,以此類推。
這種執(zhí)行方式邏輯上是沒有問題的。但是為了生成最終的字符串,這段代碼執(zhí)行過程中會(huì)生成一大堆需要垃圾回收的中間對(duì)象。
在J2SE 5.0開始提供java.lang.StringBuilder類,使用這個(gè)類所產(chǎn)生的對(duì)象預(yù)設(shè)會(huì)有16個(gè)字節(jié)的長度,你也可以自行指定初始長度,如果附加的字符超出可容納的長度,則StringBuilder對(duì)象會(huì)自動(dòng)增加長度以容納被附加的字符,如果有頻繁作字串附加的需求,使用StringBuilder會(huì)讓程序的效率大大提升,來寫個(gè)簡單的測(cè)試程序就可以知道性能差距有多大。
public class AppendStringTest {
public static void main(String[] args) {
String text = "test";
long beginTime = System.currentTimeMillis();
for(int i = 0; i < 10000; i++){
text = text + i;
}
long endTime = System.currentTimeMillis();
System.out.println("執(zhí)行時(shí)間:" + (endTime - beginTime));
StringBuilder builder = new StringBuilder("");
beginTime = System.currentTimeMillis();
for(int i = 0; i < 10000; i++){
builder.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("執(zhí)行時(shí)間:" + (endTime - beginTime));
}
}
//結(jié)果
執(zhí)行時(shí)間:456
執(zhí)行時(shí)間:3
StringBuilder是J2SE5.0引入的,在這之前java用的是StringBuffer,StringBuffer是線程安全的。因此開銷會(huì)大一些,不推薦使用