作者:邢紅瑞
轉自:http://blogger.org.cn/blog/more.asp?name=hongrui&id=11880
string和stringbuffer區別
這是好友面試的一道題,其實我知道使用的區別,StringBuffer必須new出來,StringBuffer的append的效率比string的+=的效率高,
其實發現還有很大的區別,看了看以前scjp的考題
public class Test {
public static void stringReplace (String text) {
text = text.replace('j' , 'i');
}
public static void bufferReplace (StringBuffer text) {
text = text.append("C");
}
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);
}
}
答案是 javajavaC
這是String參數傳遞,是不可變的(immutable).
而題目中第七行text = text.append (“C”),append方法會改變text中的值
而這個text與main中的textBuffer是指向同一個對象,所以對應的輸出是javac。
string的值永遠不會改變!
String a = "a";//假設a指向地址0x0001,
a = "b";//重新負值後a指向地址0x0002,但0x0001地址中保存的"a"依舊存在,但已經不再是a所指向的。
從表面上看String類型的對象改變了值,但事實是他不能改變值,只能改變指向的地址
StringBuffer則不同,直接改變指向的地址中保留的值
還有
StringBuffer s1 = new StringBuffer("a");
StringBuffer s2 = new StringBuffer("a");
s1.equals(s2)//爲什麼是false
String s1 = new String("a");
String s2 = new String("a");
s1.equals(s2)//爲什麼是true
StringBuffer類中沒有重新定義equals這個方法,因此這個方法就來自Object類,
而Object類中的equals方法是用來比較地址的,所以等於false.
String類中重新定義了equals這個方法,而且比較的是值,而不是地址。所以會是
true。
對於這樣能不能面試出真正的水平,感到懷疑。
StringBuffer
一個可變的字符序列。此類提供一個與 StringBuffer
兼容的 API,但不保證同步。該類被設計用作 StringBuffer
的一個簡易替換,用在字符串緩衝區被單個線程使用的時候(這種情況很普遍)。如果可能,建議優先採用該類,因爲在大多數實現中,它比 StringBuffer
要快。
在 StringBuilder
上的主要操作是 append
和 insert
方法,可重載這些方法,以接受任意類型的數據。每個方法都能有效地將給定的數據轉換成字符串,然後將該字符串的字符追加或插入到字符串生成器中。append
方法始終將這些字符添加到生成器的末端;而 insert
方法則在指定的點添加字符。
例如,如果 z
引用一個當前內容爲 "start
" 的字符串的生成器對象,則該方法調用 z.append("le")
將使字符串生成器包含 "startle
",而 z.insert(4, "le")
將更改字符串生成器,使之包含 "starlet
"。
通常,如果 sb 引用 StringBuilder
的實例,則 sb.append(x)
和 sb.insert(sb.length(), x)
具有相同的效果。每個字符串生成器都有一定的容量。只要字符串生成器所包含的字符序列的長度沒有超出此容量,就無需分配新的內部緩衝區。如果內部緩衝區溢出,則此容量自動增大。
將 StringBuilder
的實例用於多個線程是不安全的。如果需要這樣的同步,則建議使用 StringBuffer
。
- 從以下版本開始:
- 1.5
- 另請參見:
StringBuffer
,String
, 序列化表格