何时在Java中使用StringBuilder

kos*_*tja 341 java string performance

通常认为StringBuilder在Java中使用字符串连接通常是优选的.总是这样吗?

我的意思是:创建一个StringBuilder对象的开销,调用append()方法,最后toString()已经小了,然后将现有的字符串与+运算符连接两个字符串,或者只建议更多(超过两个)字符串?

如果有这样的阈值,它依赖于什么(可能是字符串长度,但以哪种方式)?

最后,您是否会交换+串联的可读性和简洁性,以便StringBuilder在较小的情况下(如两个,三个或四个字符串)的性能?

StringBuilder过时的Java优化技巧以及Java都市神话中,人们提到明确使用常规连接已经过时了.

Ral*_*lph 478

如果你在循环中使用字符串连接,这样的话,

String s = "";
for (int i = 0; i < 100; i++) {
    s += ", " + i;
}
Run Code Online (Sandbox Code Playgroud)

然后你应该使用StringBuilder(而不是StringBuffer)而不是a String,因为它更快,消耗更少的内存.

如果你有一个声明,

String s = "1, " + "2, " + "3, " + "4, " ...;
Run Code Online (Sandbox Code Playgroud)

那么你可以使用Strings,因为编译器会StringBuilder自动使用.

  • @haylem:你真的好吗? - 我用版本1.6.0.21检查了它,当然String循环使用了一个String Builder,但**只用于连接**(s + =","+ i;) - 所以**它创建了一个新的每个循环的字符串生成器!** - 所以它比使用一个StringBuilder要慢得多,这个StringBuilder是在循环的一侧创建的,并且在循环内只调用它的append方法. (101认同)
  • @Ralph:抱歉,有一个忙碌的一周,但我终于开始挖掘它了,如上所述,我确实错了.它确实为每个循环转弯创建一个StringBuilder.游民.我可以看到这种方式更好的情况,但我认为他们可以检测到一些可以实现增强路径检测的情况.所以那里还有改进的余地:).谢谢你让我验证一下. (60认同)
  • 实际上,现在我几乎不会使用任何其他东西而不是字符串.我曾经主张过这些,但幸运的是,随着JVM的进步,它几乎不再需要**了.如果您查看上面的字节码(至少JDK> 1.6u22),您会注意到所有内容都被StringBuilder取代.它不仅仅是单个语句,而且实际上是相当复杂的结构.我刚刚在实际代码上做了几个测试用例,实际上我没有发现任何内部不使用StringBuilders的情况.相当不错. (30认同)
  • 谢谢你,拉尔夫.简短,精确(并有示例) (16认同)
  • @Harylem:没问题 (4认同)
  • 我用jdk 1.8.0测试 - 它是相同的字节代码.此外,由于对象分配现在非常便宜,我对性能提升有点怀疑.然而,切换到显式的StringBuilder 1实例,在1000次迭代中从0~ 120ms给出了0-1ms.因此,类似情况下,关键位置仍然需要StringBuilder. (2认同)
  • 在现实生活中,我不得不修改内存中的10 MB HTML文档并将其发送给客户端。因为要进行许多复杂的更改,所以我建立了一个字符串更改表并使用`StringBuilder`构建了结果。天真的“ String + String”的提速是巨大的,最终结果可以在10秒内处理HTML。变更表将要进行成千上万的变更,因此创建和销毁如此多的自动StringBuilder对象的开销是巨大的。 (2认同)

zaw*_*tut 51

拉尔夫的答案非常棒.我宁愿使用StringBuilder类来构建/装饰String,因为它的使用更像是Builder模式.

public String decorateTheString(String orgStr){
            StringBuilder builder = new StringBuilder();
            builder.append(orgStr);
            builder.deleteCharAt(orgStr.length()-1);
            builder.insert(0,builder.hashCode());
            return builder.toString();
}
Run Code Online (Sandbox Code Playgroud)

它可以用作帮助器/构建器来构建String,而不是String本身.

  • 我不认为StringBuilder与Builder模式有任何关系。名称匹配是巧合AFAIK。 (2认同)

Ria*_*ius 38

作为一般规则,始终使用更易读的代码,并且只有在性能成为问题时才重构.在这种特定情况下,最新的JDK实际上将在任何情况下将代码优化为StringBuilder版本.

如果您在循环中或在编译器无法轻松优化的某些复杂代码中进行字符串连接,通常只需要手动执行此操作.


Mic*_*las 7

请查看:http://www.javaspecialists.eu/archive/Issue068.htmlhttp://www.javaspecialists.eu/archive/Issue105.html

在您的环境中执行相同的测试,并检查更新的JDK或Java实现是否更好地使用String或更好地执行某种类型的字符串操作StringBuilder.


Evg*_*eev 5

对于两个字符串 concat 更快,在其他情况下 StringBuilder 是更好的选择,请参阅我在连接运算符 (+) 与 concat()中的解释


Wil*_*son 5

某些编译器可能无法用StringBuilder等效替换任何字符串连接.在依赖编译时优化之前,请务必考虑源代码将使用哪些编译器.

  • 有趣的是,我并没有意识到这一点。您能否提供一个参考,说明哪些编译器替换了串联,哪些不替换? (2认同)