Java 循环后清除字符串缓冲区/生成器
如何在循环后清除Java中的字符串缓冲区,以便下一次迭代使用清除字符串缓冲区?一个选项是使用delete方法,如下所示:Java 循环后清除字符串缓冲区/生成器,java,string,buffer,Java,String,Buffer,如何在循环后清除Java中的字符串缓冲区,以便下一次迭代使用清除字符串缓冲区?一个选项是使用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()); } 有关更多信息,请参阅:我建议为每个迭代创建一个新的String
StringBuffer sb = new StringBuffer();
for (int n = 0; n < 10; n++) {
sb.append("a");
// This will clear the buffer
sb.delete(0, sb.length());
}
有关更多信息,请参阅:我建议为每个迭代创建一个新的
StringBuffer
(甚至更好)。性能差异实际上可以忽略不计,但您的代码将更短、更简单。重用StringBuffer
的最简单方法是使用方法setLength()
buf.delete(0, buf.length());
你可能有这样的情况
StringBuffer sb = new StringBuffer("HelloWorld");
// after many iterations and manipulations
sb.setLength(0);
// reuse sb
我认为这段代码更快。您有两种选择: 或使用:
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和StringBuild性能差异的基准测试结果,在循环中使用新实例或在循环中使用setLength(0)
总结是:在一个大循环中
- StringBuilder比StringBuffer快得多
- 在循环中创建新的StringBuilder实例没有 与setLength(0)的差异。(与创建新实例相比,setLength(0)的优势非常小。)
- 通过在循环中创建新实例,StringBuffer比StringBuilder慢
- StringBuffer的setLength(0)比在循环中创建新实例慢得多
公共类StringBuilderSpeed{
公共静态最终字符ch[]=新字符[]{'a','b','c','d','e','f','g','h','i'};
公共静态void main(字符串a[]{
int loopTime=9999999;
long startTime=System.currentTimeMillis();
StringBuilder sb=新的StringBuilder();
for(int i=0;i
}
循环中的新StringBuilder实例:
时间成本:3693386236243742
StringBuilder设置长度:
时间成本:3465342135573408
循环中的新StringBuffer实例:
时间成本:832783248284
StringBuffer设置长度
时间成本:228782301722894
同样,StringBuilder setLength确保我的labtop不会遇到使用如此长的StringBuffer setLength时出现问题:-)
时间成本:3448
public void clear(StringBuilder s) {
s.setLength(0);
}
用法:
StringBuilder v = new StringBuilder();
clear(v);
为了可读性,我认为这是最好的解决方案。我使用下面的代码来存储密码,以便进行临时处理,如正则表达式匹配,并在完成后将其清除。通常的删除方法不会重置所有字符,这不适合我。这个代码满足了我的要求
公共静态无效清除(StringBuilder值){
for(int i=0,len=value.length();i
稍微少一点垃圾的东西就是在循环中声明StringBuffer。啊,我认为sb.setLength(0);比在循环中声明更干净、更高效。您的解决方案与使用StringBuffer的性能优势背道而驰……我认为性能优势来自字符串的可变性,而不是保存实例化。下面是1e8迭代的快速测试:内部循环(2.97s):,外部循环(2.87s):说到性能:除非您的代码是在多线程场景中访问的,否则您应该使用StringBuilder而不是StringBuffer——请参阅javadoc:“在可能的情况下,建议优先使用该类而不是StringBuffer,因为在大多数实现中它会更快”。在外部创建SB的唯一好处是不会丢失它的内部(可能很长)字符[]。如果在第一个迭代器中它足够大,第二个循环将不需要调整任何字符[].但为了获得优势,“清晰方法”“必须保留内部数组的大小。setLength会这样做,但它也会将SB中所有未使用的字符设置为\u0000,因此,仅创建一个具有良好初始容量的新SB的性能较差。在循环内声明更好。另一个问题:为什么只在循环的一次迭代中使用SB?还有其他内部迭代吗?如果您只是想做A+B+C+D(Java编译器将在内部使用SB),那么SB是不值得的。如果您想有条件地添加字符串的一部分,它会很有帮助,但其他方面。。。只需使用“+”@MMahmoud,在代码示例中,它应该是setLength
而不是setLength
。当我看到setLength代码源代码时,它是如何工作的()这里的计数将始终大于newLength(0)?这将有性能问题。它会在每次之后创建一个新对象iteration@AdityaSingh这是一个完全合理的方法。不要在没有证据的情况下假设绩效问题。基于对正在发生的事情的理解来假设事情是智力的基础。如果你有任何证据表明绩效存在差异,请分享。(我也很高兴看到Java主要使用的统计数据,以及“主要”的定义)众所周知,分配(Java中的新关键字)比仅仅更改同一对象的某些字段更昂贵。对于“大部分”,你可以高度重放,有超过15亿的Android设备,都使用Java。我同意在某些情况下,代码可读性比性能更重要,但在这种情况下,它只是一行代码!您可以运行一个基准测试来证明分配和
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));
}
public void clear(StringBuilder s) {
s.setLength(0);
}
StringBuilder v = new StringBuilder();
clear(v);