StringBuffer 和 StringBuilder 的區別是什麼?
String 的問題
因為String是immutable的,每次的操作都會建立一個新的String物件,當操作頻繁的時候就會帶來開銷,而StringBuilder,StringBuffer內部維護的是字元陣列,每次的操作都是改變字元陣列的狀態,避免建立大量的String物件。
區別是什麼?
答:StringBuffer是執行緒安全的(synchronized),而 StringBuilder不是,所以StringBuilder效率更高,鎖的獲取和釋放會帶來開銷。
看看程式碼
不論是建立StringBuffer 還是 StringBuilder物件,都是建立一個容量為16的字元陣列。
/**
* The value is used for character storage。
*/
char
[]
value
;
/**
* The count is the number of characters used。
*/
int
count
;
AbstractStringBuilder
(
int
capacity
)
{
value
=
new
char
[
capacity
];
}
區別就是所有的方法中,比如append,前者有synchronized關鍵字修飾。
StringBuffer的append方法:
public
synchronized
StringBuffer
append
(
String
str
)
{
toStringCache
=
null
;
super
。
append
(
str
);
return
this
;
}
StringBuilder的append方法:
public
StringBuilder
append
(
String
str
)
{
super
。
append
(
str
);
return
this
;
}
雖然實際的實現是一樣的。
public
AbstractStringBuilder
append
(
String
str
)
{
if
(
str
==
null
)
return
appendNull
();
// 如果是null的話,就新增字串“null”
int
len
=
str
。
length
();
ensureCapacityInternal
(
count
+
len
);
str
。
getChars
(
0
,
len
,
value
,
count
);
// 字元陣列的複製
count
+=
len
;
return
this
;
}
toString()方法
雖然StringBuffer使用了快取,但是本質上都一樣,每次toString()都會建立一個新的String物件,而不是使用底層的字元陣列,我的理解是:StringBuffer/StringBuilder的存在是為了高效的操作字串(字元陣列)的狀態,但是當我們使用toString()的時候一定是一個穩定的狀態,具有確切的行為,底層的字元陣列仍然是可有變化的。
StringBuffer:
public
synchronized
String
toString
()
{
if
(
toStringCache
==
null
)
{
toStringCache
=
Arrays
。
copyOfRange
(
value
,
0
,
count
);
}
return
new
String
(
toStringCache
,
true
);
}
StringBuilder
:
public
String
toString
()
{
// Create a copy, don‘t share the array
return
new
String
(
value
,
0
,
count
);
}