String 的問題

因為String是immutable的,每次的操作都會建立一個新的String物件,當操作頻繁的時候就會帶來開銷,而StringBuilder,StringBuffer內部維護的是字元陣列,每次的操作都是改變字元陣列的狀態,避免建立大量的String物件。

StringBuffer 和 StringBuilder 的區別是什麼?

區別是什麼?

答: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

);

}