Java中字元串是不可變的,也就是說,每次對字元串進行操作,都會產生一個新的字元串對象。當我們需要對字元串進行頻繁的修改操作時,這種不可變性會導致性能問題。因此,Java中提供了另外一種可變的字元串緩衝區對象——StringBuffer。
一、String和StringBuffer的區別
StringBuilder類繼承自AbstractStringBuilder,是StringBuilder和StringBuffer的操作類,與StringBuffer的一個區別是StringBuilder的方法不是線程安全的,所以在單線程的環境下建議使用StringBuilder類,而在多線程下建議使用StringBuffer類。
StringBuilder操作的實體是內部的一個char[]數組,在內存中佔用連續的一塊空間,以便當它被轉成一個字元串時,可以快速地複製一份。因為最初的空間是非常小的,所以它在增長時需要擴容(默認擴一倍)。StringBuffer的擴容處理類似,但它內部是通過System.arrayCopy方法進行重新分配,這個過程是線程安全的;StringBuilder則只是分配新的數組而已,所以是非線程安全的。
下面是String和StringBuffer的區別:
String s = ""; for (int i = 0; i < 10; i++) { s += String.valueOf(i); }
上面的代碼會在內存中創建11個字元串對象,這對於頻繁修改字元串的場景來說是低效的。下面使用StringBuffer優化上面的代碼:
StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) { sb.append(i); } String s = sb.toString();
這種方式只會創建一個StringBuffer對象。
二、String和StringBuffer的性能比較
下面針對String和StringBuffer進行性能比較。
在Java中字元串是不可變的,所以每次對字元串的操作都會產生新的字元串對象,這會導致頻繁的垃圾回收。而StringBuffer是可變的,可以直接在原來的字元串緩衝區進行操作,避免了頻繁的垃圾回收。因此,在頻繁修改字元串的場景中,StringBuffer的性能比String要好。
下面是一組性能測試的結果:
public static void testString() { String s = ""; long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { s += String.valueOf(i); } long end = System.currentTimeMillis(); System.out.println("String : " + (end - start)); } public static void testStringBuffer() { StringBuffer sb = new StringBuffer(); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { sb.append(String.valueOf(i)); } long end = System.currentTimeMillis(); System.out.println("StringBuffer : " + (end - start)); } public static void main(String[] args) { testString(); testStringBuffer(); }
執行上面的代碼,可以看到,StringBuffer的性能比String要好。
三、總結
本文介紹了Java中字元串和字元串緩衝區對象——String和StringBuffer,以及它們的區別。在頻繁修改字元串的場景下,StringBuffer的性能比String要好。在單線程環境下建議使用StringBuilder類,而在多線程環境下建議使用StringBuffer類。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/200185.html