关于java:在循环之后清除字符串缓冲区/构建器

Clearing a string buffer/builder after loop

在循环之后,如何清除Java中的字符串缓冲区,以便下一次迭代使用一个清晰的字符串缓冲区?


一种选择是使用如下的删除方法:

1
2
3
4
5
6
7
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):

1
sb.setLength(0);

有关更多信息,请参阅javadoc:


重用StringBuffer的最简单方法是使用setLength()方法。

public void setLength(int newLength)

你可能有这样的情况

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


您有两种选择:

要么使用:

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

或使用:

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

注释

避免在循环中声明StringBufferStringBuilder对象,否则它将在每次迭代中创建新对象。创建对象需要系统资源、空间和时间。因此,从长远来看,如果可能,避免在循环中声明它们。


我建议为每个迭代创建一个新的StringBuffer(甚至更好,StringBuilder)。性能差异确实可以忽略不计,但是您的代码将变得更短和简单。


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

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

用途:

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

对于可读性,我认为这是最好的解决方案。


答案已经很好了。只需为StringBuffer和StringBuild性能差异添加一个基准结果,即在循环中使用新实例或在循环中使用setLength(0)。

总结是:在一个大循环中

  • StringBuilder比StringBuffer快得多
  • 在循环中新建StringBuilder实例没有与设定长度(0)的差异。(setlength(0)比创建新实例有非常小的优势。)
  • 通过在循环中创建新实例,StringBuffer比StringBuilder慢
  • StringBuffer的setLength(0)非常慢于在循环中创建新实例。

非常简单的基准测试(我只是手动更改代码并执行不同的测试):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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实例:时间成本:3693386236243742

StringBuilder设置长度:时间成本:3465、3421、3557、3408

循环中的新StringBuffer实例:时间成本:8327、8324、8284

字符串缓冲区设置长度时间成本:22878、23017、22894

同样,为了确保不是我的Labtop,StringBuilder的setLength对StringBuffer的setLength使用了这么长的长度有一些问题:-)时间成本:3448


1
2
3
StringBuffer sb = new SringBuffer();
// do something wiht it
sb = new StringBuffer();

我认为这个代码更快。