Java中的字符串连接 - 何时使用+,StringBuilder和concat

时间:2011-10-19 07:35:00

标签: java string

我们什么时候应该使用+来连接字符串,什么时候首选StringBuilder?何时适合使用concat。

我听说StringBuilder更适合循环中的连接。为什么会这样?

感谢。

9 个答案:

答案 0 :(得分:45)

现代Java编译器通过StringBuilder的追加转换你的+操作。我的意思是说如果你做str = str1 + str2 + str3,那么编译器将生成以下代码:

StringBuilder sb = new StringBuilder();
str = sb.append(str1).append(str2).append(str3).toString();

您可以使用DJ或Cavaj反编译代码来确认:) 所以现在使用+或StringBuilder更多是选择而不是性能优势:)

然而,考虑到编译器没有为您执行此操作的情况(如果您使用任何私有Java SDK来执行此操作,那么可能会发生这种情况),那么确定StringBuilder是最终避免大量不必要的方式{ {1}}对象。

答案 1 :(得分:31)

我倾向于在性能受到关注的代码路径上使用StringBuilder。循环中重复的字符串连接通常是一个很好的选择。

首选StringBuilder的原因是+concat每次调用它们时都会创建一个新对象(前提是右侧参数不为空)。这可以很快加起来很多对象,几乎所有对象都是完全没必要的。

正如其他人所指出的,当你在同一个语句中多次使用+时,编译器通常可以为你优化这个。但是,根据我的经验,当连接发生在单独的语句中时,此参数不适用。它肯定对循环没有帮助。

说完这一切之后,我认为最重要的应该是编写清晰的代码。有一些很好的分析工具可用于Java(我使用YourKit),这使得很容易找出性能瓶颈并优化它重要的位。

P.S。我从来不需要使用concat

答案 2 :(得分:15)

来自Java/J2EE Job Interview Companion

  

<强> String

     

String是不可变的:您无法修改String对象,但可以通过创建新实例来替换它。创建一个新实例相当昂贵。

//Inefficient version using immutable String
String output = "Some text";
int count = 100;
for (int i = 0; i < count; i++) {
    output += i;
}
return output;
     

上面的代码将构建99个新的String个对象,其中98个将被立即丢弃。创建新对象效率不高。

     

<强> StringBuffer / StringBuilder

     

StringBuffer是可变的:当您想要修改内容时,请使用StringBufferStringBuilder。在Java 5中添加了StringBuilder,它在所有方面都与StringBuffer完全相同,只是它不同步,这使得它更快,但代价是不是线程安全的。

//More efficient version using mutable StringBuffer
StringBuffer output = new StringBuffer(110);
output.append("Some text");
for (int i = 0; i < count; i++) {
  output.append(i);
}
return output.toString();
     

上面的代码只创建了两个新对象,即StringBuffer和返回的最终StringStringBuffer会根据需要进行扩展,但这样做会很昂贵,因此最好从一开始就使用正确的大小初始化StringBuffer,如图所示。

答案 3 :(得分:5)

如果所有连接元素都是常量(例如:"these" + "are" + "constants"),那么我更喜欢+,因为编译器会为你内联串联。否则,使用StringBuilder是最有效的方法。

如果对非常量使用+,编译器也将在内部使用StringBuilder,但调试变得很糟糕,因为使用的代码不再与源代码相同。

答案 4 :(得分:2)

我的建议如下:

  • +:在连接2或3个字符串时使用,只是为了使代码简洁易读。
  • StringBuilder:在构建复杂的字符串输出时或在考虑性能时使用。
  • String.format:你没有在你的问题中提到这个,但它是我创建字符串的首选方法,因为它使代码在我看来最可读/最简洁,对日志语句特别有用。
  • concat:我认为我没有理由使用它。

答案 5 :(得分:1)

如果您进行大量操作,请使用StringBuilder通常循环是一个很好的指示。

这样做的原因是使用正常连接会产生大量中间String对象,这些对象无法轻松“扩展”(即每个连接操作都会产生副本,需要内存和CPU时间)。另一方面,StringBuilder只需要在某些情况下复制数据(在中间插入一些东西,或者因为结果变大而不得不调整大小),这样就可以节省那些复制操作。

使用concat()与使用+相比并没有什么好处(对于单个+来说,它可能会稍微快一点,但是一旦你a.concat(b).concat(c),它实际上会是a + b + c慢于{{1}})。

答案 6 :(得分:1)

编译器的性能增益适用于连接常量。 其余的用法实际上比直接使用StringBuilder慢。

使用“+”没有问题,例如用于为Exception创建消息,因为它不经常发生,并且应用程序已经在某种程度上已经被搞砸了。 避免在循环中使用“+”。

要创建有意义的消息或其他参数化字符串(例如Xpath表达式),请使用 String.format - 它的可读性要高得多。

答案 7 :(得分:1)

对单个语句使用+,对多个语句/循环使用StringBuilder。

答案 8 :(得分:1)

我建议使用concat进行两个字符串连接和StringBuilder,请参阅我对concatenation operator (+) vs concat()的解释