关于java:如何清除或清空StringBuilder?

How can I clear or empty a StringBuilder?

本问题已经有最佳答案,请猛点这里访问。

我在一个循环中使用了一个StringBuilder,每x次迭代我都想清空它,从一个空的StringBuilder开始,但是我看不到任何类似于.NET StringBuilder的方法。在文档中,只需删除看起来过于复杂的方法。

那么,在Java中清除EDCOX1 0的最好方法是什么?


两种工作方式:

  • 使用stringBuilderObj.setLength(0)
  • new StringBuilder()分配一个新的,而不是清除缓冲区。

  • 基本上有两种选择,使用setLength(0)重置StringBuilder或在每个迭代中创建一个新的。根据使用情况,两者都有优缺点。

    如果您事先知道了StringBuilder的预期容量,那么每次创建一个新的容量应该和设置一个新的长度一样快。它还将帮助垃圾收集器,因为每个StringBuilder都是相对较短的生命周期,并且GC为此进行了优化。

    当您不知道容量时,重用同一个StringBuilder可能会更快。每次追加时超过容量时,都必须分配新的备份数组,并且必须复制以前的内容。通过重用同一个StringBuilder,它将在一些迭代之后达到所需的容量,之后将不会有任何复制。


    delete并不太复杂:

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

    您还可以执行以下操作:

    1
    myStringBuilder.setLength(0);


    如果查看StringBuilder或StringBuffer的源代码,setLength()调用只会重置字符数组的索引值。使用setlength方法的imho总是比新的分配更快。他们应该将该方法命名为"clear"或"reset",以便更清晰。


    我将投票支持sb.setLength(0);,不仅因为它是一个函数调用,而且因为它实际上没有将数组复制到像sb.delete(0, builder.length());这样的另一个数组中。它只需将其余字符填充为0,并将长度变量设置为新的长度。

    您可以查看它们的实现,从这里验证我在setLength函数和delete0函数的观点。


    您应该使用sb.delete(0, sb.length())sb.setLength(0),而不是创建新的stringbuilder()。

    有关性能,请参阅这篇相关文章:在循环中重用StringBuilder更好吗?


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

    是个简单的方法。


    我认为这里的许多答案可能缺少StringBuilder中包含的质量方法:.delete(int start, [int] end)。我知道这是一个迟来的答复;然而,这应该被告知(并解释得更彻底一些)。

    假设您有一个StringBuilder表——您希望在整个程序中动态地修改它(我现在正在处理的一个表会这样做),例如。

    1
    StringBuilder table = new StringBuilder();

    如果您正在循环使用该方法并更改内容,请使用该内容,然后希望放弃该内容以"清理"下一个迭代的StringBuilder,您可以删除它的内容,例如。

    1
    table.delete(int start, int end).

    开始和结束是要删除的字符的索引。不知道字符长度,想删除整个内容?

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

    现在,对于踢球员来说。如前所述,当频繁更改时,StringBuilders会产生大量开销(并可能导致线程方面的安全问题);因此,如果您的StringBuilder用于与用户接口,则使用StringBufferStringBuilder相同(少数例外)。


    如果性能是主要问题…反讽(IMO)是Java构建格式化进入缓冲区的文本将比CPU /重排序/垃圾收集在CPU上耗费更多的时间。嗯,可能不是GC,这取决于您创建和丢弃了多少构建器。

    但是简单地将一个复合字符串("hello world of"+6e9+"earthlings.")添加到缓冲区可能会使整个事情变得无关紧要。

    而且,实际上,如果StringBuilder涉及的内容复杂而冗长,比简单的EDCOX1(4)要长(无论如何,Java可能在后台使用生成器)。

    就我个人而言,我尽量不滥用GC。所以,如果这是一个将在快速射击场景中大量使用的东西,比如说,编写调试输出消息…我只是假设在其他地方声明它,然后将其归零以便重用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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());
        }
    }