String 和 StringBuffer區別
JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操作字串,即包含多個字元的字元資料.這個String類提供了數值不可改變的字串.而這個StringBuffer類提供的字串進行修改.當你知道字元資料要改變的時候你就可以使用 StringBuffer.典型地,你可以使用 StringBuffers來動態構造字元資料.
一、String的使用方法:
1. 首先String不屬於8種基本資料型別,String是一個物件.因為物件的預設值是null,所以String的預設值也是null;但它又是一種特殊的物件,有其它物件沒有的一些特性. 2. new String()和new String("")都是申明一個新的空字串,是空串不是null;
結果為:<pre name="code" class="java"><span style="font-size:18px;"> public class Test { public static void main(String [] args) { String s0="java"; String s1="java"; String s2="ja" + "va"; System.out.println( s0==s1 ); System.out.println( s0==s2 ); } } </span>
true
true 首先,我們要知道Java會確保一個字串常量只有一個拷貝.
因為例子中的s0和s1中的"java"都是字串常量,它們在編譯期就被確定了,所以s0==s1為true;而"ja"和"va"也都是字串常量,當一個字串由多個字串常量連線而成時,它自己肯定也是字串常量,所以s2也同樣在編譯期就被解析為一個字串常量,所以s2也是常量池中"java"的一個引用.
所以我們得出s0==s1==s2; 3.2 String str=new String ("java")
結果為:<span style="font-size:18px;"> public class Test { public static void main(String [] args) { String s0="java"; String s1=new String("java"); String s2="ja" + new String("va"); System.out.println( s0==s1 ); System.out.println( s0==s2 ); System.out.println( s1==s2 ); } } </span>
false
false
false
用new String() 建立的字串不是常量,不能在編譯期就確定,所以new String() 建立的字串不放入常量池中,它們有自己的地址空間.
3.2例子中s0還是常量池中"java"的應用,s1因為無法在編譯期確定,所以是執行時建立的新物件"java"的引用,s2因為有後半部分new String("va")所以也無法在編譯期確定,所以也是一個新建立物件"java"的應用;明白了這些也就知道為何得出此結果了.
4. 關於equals()和==:
這個對於String簡單來說就是比較兩字串的Unicode序列是否相當,如果相等返回true;而==是比較兩字串的地址是否相同,也就是是否是同一個字串的引用。
二、Java StringBuffer的使用方法:
1.java.lang.StringBuffer代表可變的字元序列;2.StringBuffer和String類似,但StringBuffer可以對其字串進行改變;
3.StringBuffer類的常見構造方法:
StringBuffer()
建立一個不包含字元序列的"空"的StringBuffer物件;
StringBuffer(String str)
建立一個StringBuffer物件,包含與String物件str相同的字元序列.
4.常用方法:
public StringBuffer append()
可以為該StringBuffer物件新增字元序列,返回新增後的該StringBuffer物件引用;
public StringBuffer insert()
可以為該StringBuffer物件在指定位置插入字元序列,返回修改後的該
三、String 與StringBuffer的區別
1. String:在String類中沒有用來改變已有字串中的某個字元的方法,由於不能改變一個java字串中的某個單獨字元,所以在JDK文件中稱String類的物件是不可改變的。然而,不可改變的字串具有一個很大的優點:編譯器可以把字串設為共享的。
2.StringBuffer:StringBuffer類屬於一種輔助類,可預先分配指定長度的記憶體塊建立一個字串緩衝區。
這樣使用StringBuffer類的append方法追加字元 比 String使用 + 操作符新增字元 到 一個已經存在的字串後面有效率得多。
因為使用 + 操作符每一次將字元新增到一個字串中去時,字串物件都需要尋找一個新的記憶體空間來容納更大的字串,這無凝是一個非常消耗時間的操作。新增多個字元也就意味著要一次又一次的對字串重新分配記憶體。使用StringBuffer類就避免了這個問題.
3.String 字串常量
StringBuffer 字串變數(執行緒安全)
簡要的說, String 型別和 StringBuffer 型別的主要效能區別其實在於 String 是不可變的物件,
因此在每次對 String 型別進行改變的時候其實都等同於生成了一個新的 String 物件,
然後將指標指向新的 String 物件,所以經常改變內容的字串最好不要用 String ,
因為每次生成物件都會對系統性能產生影響,特別當記憶體中無引用物件多了以後, JVM 的 GC 就會開始工作,那速度是一定會相當慢的。
而如果是使用 StringBuffer 類則結果就不一樣了,每次結果都會對 StringBuffer 物件本身進行操作,而不是生成新的物件,再改變物件引用。
所以在一般情況下我們推薦使用 StringBuffer ,特別是字串物件經常改變的情況下。
而在某些特別情況下, String 物件的字串拼接其實是被 JVM 解釋成了 StringBuffer 物件的拼接,所以這些時候 String 物件的速度並不會比 StringBuffer 物件慢,而特別是以下的字串物件生成中, String 效率是遠要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你會很驚訝的發現,生成 String S1 物件的速度簡直太快了,而這個時候 StringBuffer 居然速度上根本一點都不佔優勢。
其實這是 JVM 的一個把戲,在 JVM 眼裡,這個 String S1 = “This is only a” + “ simple” + “test”;
其實就是: String S1 = “This is only a simple test”; 所以當然不需要太多的時間了。
但大家這裡要注意的是,如果你的字串是來自另外的 String 物件的話,速度就沒那麼快了,
譬如:String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
這時候 JVM 會規規矩矩的按照原來的方式去做。
<span style="font-size:18px;">
public class Test {
public static void stringReplace(String text) {
//把textString的地址copy給text
//在這個類中相當於又新new出一個text的物件,新物件text指向java
//text.replace('j', 'i');的結果是"iava"
text = text.replace('j', 'i');
//輸出結果為新物件中的值iava
System.out.println (text);
}
public static void bufferReplace(StringBuffer text) {
//textBuffer的地址copy給text
//然後沿著text指向的字串(其實也就是textBuffer指向的物件)操作,新增一個"C"
//與原物件操作的是同一塊記憶體區域
text = text.append("C");
//輸出結果為是原來物件改變後的值javac
System.out.println (text);
}
public static void main(String args[]) {
String textString = new String("java");
StringBuffer textBuffer = new StringBuffer("java");
stringReplace(textString);
bufferReplace(textBuffer);
System.out.println(textString + textBuffer);
}
}
</span>
輸出:
iava javaC
javajavaC