2010-02-11 41 views
91

如何在循環後清除Java中的字符串緩衝區,以便下一次迭代使用明確的字符串緩衝區?清除循環後的字符串緩衝區/構建器

+2

另一個問題:爲什麼你只用一個SB來循環一次迭代?是否有另一個內部迭代?如果你只是想要做A + B + C + D(Java編譯器將在內部使用一個SB),SB是不值得的。它有助於你有條件地添加部分字符串,否則...只需使用「+」即可。 – helios 2010-02-11 09:09:58

+0

您madarchod atleast接受答案 – 2017-10-10 12:40:32

回答

111

一種選擇是使用delete方法如下:

StringBuffer sb = new StringBuffer(); 
for (int n = 0; n < 10; n++) { 
    sb.append("a"); 

    // This will clear the buffer 
    sb.delete(0, sb.length()); 
} 

另一種選擇(位清潔劑)使用setLength(INT LEN)

sb.setLength(0); 

Javadoc更多信息:

+15

稍微有些垃圾就是在循環內部聲明StringBuffer。 – 2010-02-11 05:33:49

+9

啊,我覺得sb.setLength(0);比在循環中聲明它更清潔並且更高效。你的解決方案違背了使用StringBuffer的性能優勢... – Jon 2010-02-11 05:38:19

+4

我認爲性能優勢來自字符串可變性,而不是保存實例化。這裏是1e8迭代的快速測試:內循環(2.97s):http://ideone.com/uyyTL14w,外循環(2.87s):http://ideone.com/F9lgsIxh – 2010-02-11 05:46:42

5
buf.delete(0, buf.length()); 
5

我建議肌酸g爲每個迭代新的StringBuffer(或甚至更好,StringBuilder)。性能差異實際上可以忽略不計,但您的代碼會更短,更簡單。

+0

由於Java現在主要用於Android,我不確定在循環中分配一個新對象是性能和電池壽命的良好實踐。通過清除「StringBuilder」增加的代碼複雜度與潛在的性能增益相比是最小的。 – 2015-11-26 08:20:30

+1

如果您有任何此類表現差異的證據,請分享。 (我也很高興看到統計數據顯示了Java最常用的地方以及「主要」的定義。) – 2015-11-26 11:07:49

+1

衆所周知,分配(Java中的new關鍵字)比僅改變相同的字段更昂貴目的。對於可以高度重複的「大部分」,全部使用Java的Android設備超過15億個。 – 2015-11-26 11:17:24

39

重用StringBuffer最簡單的方法是使用方法setLength()

public void setLength(int newLength)

你可能有類似的情況下

StringBuffer sb = new StringBuffer("HelloWorld"); 
// after many iterations and manipulations 
sb.setLength(0); 
// reuse sb 
+2

@MMahmoud,在代碼示例中它應該讀取'setLength'而不是'setlength'。 – OnaBai 2012-12-07 15:58:23

0
StringBuffer sb = new SringBuffer(); 
// do something wiht it 
sb = new StringBuffer(); 

我覺得這個代碼是更快的。

+2

這會產生性能問題。它在每次迭代後創建一個新對象 – 2015-06-19 14:34:33

+0

@AdityaSingh這是一個完全合理的方法。沒有證據,不要假設性能問題。 – shmosel 2018-01-16 23:23:18

13

你有兩個選擇:

要麼使用:

sb.setLength(0); // It will just discard the previous data, which will be garbage collected later. 

或使用:

sb.delete(0, sb.length()); // A bit slower as it is used to delete sub sequence. 

注:

可以避免聲明否則循環也將在StringBufferStringBuilder對象每次迭代創建新對象。創建對象需要系統資源和空間,同時也需要時間。因此,長期來看,如果可能的話,避免在循環中聲明它們。

0

那裏已經有很好的答案。只需爲循環中的StringBuffer和StringBuild性能差異使用新實例添加基準結果或在循環中使用setLength(0)即可。

的總結是:在一個大的循環

  • 的StringBuilder比StringBuffer的
  • 新建StringBuilder實例中環路沒有 中用SetLength函數的區別快得多(0)。 (setLength(0)比創建新實例非常非常非常小的優勢。)
  • StringBuffer的是在循環創建新實例
  • setLength比的StringBuilder慢的StringBuffer(0)比在環路創建新實例非常慢。

非常簡單的基準(我只是手動修改代碼,做不同的測試):

public class StringBuilderSpeed { 
public static final char ch[] = new char[]{'a','b','c','d','e','f','g','h','i'}; 

public static void main(String a[]){ 
    int loopTime = 99999999; 
    long startTime = System.currentTimeMillis(); 
    StringBuilder sb = new StringBuilder(); 
    for(int i = 0 ; i < loopTime; i++){ 
     for(char c : ch){ 
      sb.append(c); 
     } 
     sb.setLength(0); 
    } 
    long endTime = System.currentTimeMillis(); 
    System.out.println("Time cost: " + (endTime - startTime)); 
} 

}在循環

新StringBuilder實例: 時間成本:3693,3862,3624, 3742

的StringBuilder setLength: 時間成本:3465,3421,3557,3408

新的StringBuffer實例中循環: 時間成本:8327,8324,8284

StringBuffer的setLength 時間成本:22878,23017,22894

同樣的StringBuilder setLength保證不是我的labtop得到了使用此類一些問題長StringBuffer的setLength :-) 時間成本:3448

1
public void clear(StringBuilder s) { 
    s.setLength(0); 
} 

用法:

StringBuilder v = new StringBuilder(); 
clear(v); 

爲了可讀性,我認爲這是最好的解決方案。