雜談——String、StringBuffer、StringBuilder和StringTokenizer有什麼區別
字串是Java中很特殊的一個東西,本帥博主自學習Java以來被這小兔崽子拽入多次坑。
而Java語言中有四個類可以對字元或者字串進行操作,它們分別是Character、String、StringBuffer和StingTokenizer。
其中Character用於單個字元操作,String用於字串操作,屬於不可變類,而StringBuffer也是用於字串操作,不同之處是StringBuffer屬於可變類。
當然,除了這些它們還有其他的一些特性。
他們的具體使用本帥博主這裡就不說了,關於String類和StringBuffer的一些方法可以看看這位博主列出來的:
Java中String,StringBuffer,StringBuilder常用方法及使用例項
今天我們就來看看這四個傢伙都有啥特殊之處。
1.String與StringBuffer
上文說到,String是不可變類,也就是說,String物件一旦被建立,其值就不能被更改,而StringBuffer是可變類,當物件被建立後仍然可以對其值進行更改。由於String是不可變類,因此適合在需要被共享的場合中使用;而當一個字串經常需要被修改的時候,最好使用StringBuffer來實現。
為什麼?因為如果用String來儲存一個經常被修改的字串時,在字串被修改的時候會比StringBuffer多出來很多附加的操作,同時會生成很多無用的物件,由於這些無用的物件會被垃圾回收器回收,因此會影響程式的效能。在規模很小的專案中這個影響很小,但是在一個規模的專案中,這回對程式的執行效率帶來很大的影響。
看到這裡大家可能有些懵了,上面明明說String是個不可變類,為什麼還可以用來儲存一個經常被修改的字串呢?其實,這裡說的儲存一個經常被修改的字串指的並不是直接對原字串進行修改。
在這段程式碼中,s原先指向一個String物件,內容是hello,然後我們對s進行+操作,那麼s所指向的那個物件是否發生了變化呢?答案是沒有,這時,s不再指向原來的那個物件了,而指向另一個String物件,內容為hello world ,原來的那個物件還存在於記憶體中(沒有人用它的話會被回收),只是s這個引用變數不再指向它了。我們來看看String字串修改的原理是什麼樣的。
String字串修改實現的原理如下:
當用String型別來對字串進行修改的時候,其實現方法是首先建立一個StingBuffer,其次再呼叫StingBuffer的append()方法,最後呼叫StringBuffer的toString()方法把結果返回。
示例如下:
String s="Hello";
s+="World";
以上程式碼等價於:
StringBuffer s1=new StringBuffer(s);
s1.append("World");
s=s1.toString();
由此可以看出,上述過程比使用StringBuffer多了一些附加的操作,同時也生成了一個臨時的物件,從而導致程式的執行效率降低。
那麼這些附加的操作將對程式的執行效率造成怎麼樣的影響呢?
我們來通過一個小例子來看看。
public class TestClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
testString();
testStringBuffer();
}
public static void testString() {
String s="Hello";
String s1="World";
long start=System.currentTimeMillis();
for(int i=0;i<10000;i++)
{
s+=s1;
}
long end=System.currentTimeMillis();
long runTime=(end-start);
System.out.println("testString:"+runTime);
}
public static void testStringBuffer() {
StringBuffer s=new StringBuffer("Hello");
String s1="World";
long start=System.currentTimeMillis();
for(int i=0;i<10000;i++)
{
s.append(s1);
}
long end=System.currentTimeMillis();
long runTime=(end-start);
System.out.println("testStringBuffer:"+runTime);
}
}
執行結果如下:
從上面的程式執行結果我們可以發現,當一個字串需要經常被修改的時候,使用StringBuffer要比String好很多。
此外,String與StringBuffer的另外一個區別在於當例項化String的時候,可以利用建構函式(String s1=new Sting("world"))的方式來對其進行初始化,也可以用賦值(String s="Hello")的方式來初始化,而StingBuffer只能使用建構函式(StringBuffer s=new StringBuffer("Hello"))的方式來初始化。
2.StringBuilder
StringBuilder也是可以被修改的字串,它與StringBuffer類似,都是字串緩衝區,但是StringBuilder不是執行緒安全的。
因此,如果只在單執行緒中使用字串緩衝區,使用StringBuilder的效率會高一些。
而當多個執行緒訪問的時候,最好使用執行緒安全的StringBuffer,因為StringBuffer必要時可以對這些方法進行同步,所以任意特定實力上的所有操作就好像是以序列順序發生的,該順序與所涉及的每個執行緒進行的方法呼叫順序一致。
3.StringTokenizer
StringTokenizer是用來分割字串的工具類。我們直接看一下示例:
package Test;
import java.util.StringTokenizer;
public class testStringTokenizer {
public static void main(String[] args) {
// TODO Auto-generated method stub
StringTokenizer st=new StringTokenizer("This is Searchin's home");
while(st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
}
}
執行結果如下:
3.總結
在執行效率方面,StringBuilder最高,StringBuffer次之,String最低,鑑於這一情況,一般而言,如果要操作的資料量比較小,則優先使用String類;如果是在單執行緒下操作大量資料的話,則用StringBuilder;如果是在多執行緒下操作大量資料,則優先考慮StringBuffer。
好啦,以上就是關於String的四個類的相關知識總結啦,如果大家有什麼不明白的地方或者發現文中有描述不好的地方,歡迎大家留言評論,我們一起學習呀。
Biu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~pia!