我在循环中使用StringBuilder并且每次x迭代我想要清空它并以空StringBuilder
开头,但我看不到任何类似于.NET的方法{文档中的{3}},只是看似过于复杂的StringBuilder.Clear方法。
那么在Java中清除StringBuilder
的最佳方法是什么?
答案 0 :(得分:650)
两种工作方式:
stringBuilderObj.setLength(0)
。new StringBuilder()
分配新的,而不是清除缓冲区。答案 1 :(得分:284)
基本上有两种选择,使用setLength(0)
重置StringBuilder或在每次迭代中创建一个新的。根据用途,两者都有利弊。
如果您事先知道StringBuilder的预期容量,则每次创建一个新容量应该与设置新长度一样快。它也将有助于垃圾收集器,因为每个StringBuilder都会相对较短,并且gc已针对此进行了优化。
当您不知道容量时,重用相同的StringBuilder可能会更快。每次超出附加时的容量时,都必须分配新的后备阵列,并且必须复制先前的内容。通过重用相同的StringBuilder,它将在一些迭代后达到所需的容量,之后将不再进行任何复制。
答案 2 :(得分:70)
delete
并不过分复杂:
myStringBuilder.delete(0, myStringBuilder.length());
你也可以这样做:
myStringBuilder.setLength(0);
答案 3 :(得分:28)
如果查看StringBuilder或StringBuffer的源代码,setLength()调用只会重置字符数组的索引值。使用setLength方法的IMHO总是比新的分配更快。他们应该将方法命名为“清除”或“重置”,以便更清楚。
答案 4 :(得分:17)
我投票给sb.setLength(0);
不仅因为它是一个函数调用,而且因为它实际上并没有将数组复制到另一个数组中sb.delete(0, builder.length());
。它只是将剩余的字符填充为0,并将长度变量设置为新的长度。
您可以查看其实施情况,以setLength
函数和delete0
函数here验证我的观点。
答案 5 :(得分:6)
您应该使用sb.delete(0, sb.length())
或sb.setLength(0)
而不是创建新的StringBuilder()。
请参阅此相关帖子了解效果: Is it better to reuse a StringBuilder in a loop?
答案 6 :(得分:4)
StringBuilder s = new StringBuilder();
s.append("a");
s.append("a");
// System.out.print(s); is return "aa"
s.delete(0, s.length());
System.out.print(s.length()); // is return 0
是简单的方法。
答案 7 :(得分:2)
如果性能是主要考虑因素......具有讽刺意味的是(IMO)是用于格式化进入的文本的Java结构,缓冲区在CPU上的耗时要远远超过alloc / realloc / garbage collection ...好吧,可能不是GC,取决于你创建和丢弃的构建器数量。
但是简单地将一个复合字符串("" + 6E9 +"地球人。"的Hello World)附加到缓冲区可能会使整个问题变得无关紧要。
而且,实际上,如果StringBuilder涉及的内容是复杂而冗长的,而不是简单的String str = "Hi";
(更不用说Java可能在后台使用构建器)。
就个人而言,我尽量不滥用GC。因此,如果它会在快速火灾场景中被大量使用 - 例如,编写调试输出消息......我只是假设在其他地方声明它并将其归零以供重用。
class MyLogger {
StringBuilder strBldr = new StringBuilder(256);
public LogMsg( String stuff ) {
strBldr.setLength(0);
// ... prepend status level
strBldr.append("Info");
// ... prepend timestamp
strBldr.append(" " + getTimestamp());
// ... user msg
strBldr.append(":" + msg);
log.write(strBldr.toString());
}
}
答案 8 :(得分:2)
我认为此处的许多答案可能缺少StringBuilder
中包含的质量方法:.delete(int start, [int] end)
。我知道这是一个迟到的回复;但是,这应该是已知的(并且更详细地解释)。
让我们假设您有一个StringBuilder表 - 您希望在整个程序中动态修改它(我现在正在处理的那个),例如,
StringBuilder table = new StringBuilder();
如果您循环使用该方法并更改内容,请使用内容,然后将内容丢弃到"清理" {@ 1}}用于下一次迭代,您可以删除它的内容,例如
StringBuilder
开始和结束是您要删除的字符的索引。不知道字符的长度,想要删除整个内容吗?
table.delete(int start, int end).
现在,对于踢球者。如前所述,table.delete(0, table.length());
经常更改会占用大量开销(并且可能导致线程安全问题);因此,使用StringBuilders
- 与StringBuffer
相同(除了少数例外) - 如果您的StringBuilder
用于与用户进行交互。