StringBuilder附加vs +

时间:2011-10-25 09:21:33

标签: java string performance

这两行之间有什么区别?

stringBuilder.append("Text " + counter + " more text");
stringBuilder.append("Text ").append(counter).append(" more text");

假设计数器是一个递增的int,第一行是否在每次调用时都创建一个字符串"Text 0 more text""Text 1 more text"等,而第二行只创建这两个字符串一次:{{ 1}}和"Text "?这是对的吗?

5 个答案:

答案 0 :(得分:15)

简而言之,是的,除了每次都重复使用"Text "" more text"的相同字符串文字。

第二种变体更有效,因为它将三个组件中的每一个直接写入StringBuilder

相反,第一个变体创建另一个 - 未命名 - StringBuilder,将三个组件写入其中,调用其toString()方法并将结果写入命名的stringBuilder

总之,第一个变体创建了一个额外的StringBuilder对象和一个额外的String对象,并且比第二个变体复制了两倍的字符串数据。

答案 1 :(得分:3)

是的(大部分)是正确的。

实际上,第二个根本不会创建新的字符串,因为它每次都重用相同的字符串。它将使用“文本”和“更多文本”字符串的实际版本。

第一个将使用编译器生成的StringBuilder为“Text 1 more text”和“Text 2 more text”创建一个字符串。

答案 2 :(得分:1)

是的,你的解释是(几乎)正确。

第一行始终创建String对象,如"Text 0 more text",而第二行创建此类String对象。

第二行不创建 *所有String的任何* "Text "个对象和" more text" String个文字每次执行该行时都不会重新创建。它们只创建一次。

然而,stringBuilder对{{1}}的影响完全相同。

答案 3 :(得分:1)

几乎是正确的。

我会说更多。由于java字符串缓存所有硬编码字符串,因此不会在每次迭代时创建字符串“Text”和“more text”的实例。

答案 4 :(得分:1)

这取决于Java是否实际上是字符串,但它仍然效率低下。

字符串是不可变的,所以,如果你使用.append(“String”+ something +“String”),你强制Java创建一堆新的字符串,这样它最终可以用最终的字符串添加到缓冲区。这是一个经常被遗忘的内存耗尽,我已经看到通过消除这种类型的代码在Web应用程序中显着改进了内存使用。