【发布时间】:2011-01-15 14:16:50
【问题描述】:
如何在循环后清除 Java 中的字符串缓冲区,以便下一次迭代使用清除字符串缓冲区?
【问题讨论】:
-
另一个问题:为什么你只在循环的一次迭代中使用 SB?是否还有另一个内部迭代?如果您只是想做 A+B+C+D(Java 编译器将在内部使用 SB),那么 SB 是不值得的。如果您想有条件地添加字符串的一部分,它会有所帮助,否则......只需使用“+”。
如何在循环后清除 Java 中的字符串缓冲区,以便下一次迭代使用清除字符串缓冲区?
【问题讨论】:
我使用下面的代码来存储密码以进行临时处理,如正则表达式匹配,并在完成后将其清除。通常的删除方法不会重置所有字符,这不适合我。这段代码满足了我的要求。
public static void clear(StringBuilder value) {
for (int i = 0, len = value.length(); i < len; i++) {
value.setCharAt(i, Character.MIN_VALUE);
}
value.setLength(0);
}
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("clear this password");
// use & process sb
clear(sb);
}
【讨论】:
public void clear(StringBuilder s) {
s.setLength(0);
}
用法:
StringBuilder v = new StringBuilder();
clear(v);
为了可读性,我认为这是最好的解决方案。
【讨论】:
那里已经有了很好的答案。只需为 StringBuffer 和 StringBuild 性能差异添加基准结果,在循环中使用新实例或在循环中使用 setLength(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 设置长度: 时间成本:3465、3421、3557、3408
循环中的新 StringBuffer 实例: 时间成本:8327、8324、8284
StringBuffer 设置长度 时间成本:22878、23017、22894
再次使用 StringBuilder setLength 确保我的 labtop 在使用这么长的 StringBuffer setLength 时不会遇到问题 :-) 时间成本:3448
【讨论】:
你有两个选择:
任意使用:
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.
避免在循环中声明StringBuffer 或StringBuilder 对象,否则每次迭代都会创建新对象。创建对象需要系统资源、空间和时间。因此,从长远来看,尽可能避免在循环中声明它们。
【讨论】:
StringBuffer sb = new SringBuffer();
// do something wiht it
sb = new StringBuffer();
我认为这段代码更快。
【讨论】:
重用StringBuffer最简单的方法是使用setLength()方法
public void setLength(int newLength)
你可能有这样的情况
StringBuffer sb = new StringBuffer("HelloWorld");
// after many iterations and manipulations
sb.setLength(0);
// reuse sb
【讨论】:
setLength 而不是 setlength。
我建议为每次迭代创建一个新的StringBuffer(或者更好的是StringBuilder)。性能差异确实可以忽略不计,但您的代码会更短更简单。
【讨论】:
一种选择是使用删除方法,如下所示:
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:
【讨论】:
buf.delete(0, buf.length());
【讨论】: