最佳实践/性能:将StringBuilder.append与String.concat混合使用

时间:2012-04-09 19:51:21

标签: java string stringbuilder string-concatenation

我正在尝试理解最佳实践是什么以及为什么将字符串文字和变量连接到不同的情况。例如,如果我有这样的代码

StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
    .append(B_String).append("CCCCCCCCCCC").append(D_String)
    .append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
    .append("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");

这是这样做的吗?从this post开始,我注意到Strings上的+运算符创建了一个StringBuilder的新实例,连接了操作数,并返回了一个String转换,这似乎比调用{{1}更多的工作};所以,如果这是真的,那就不可能了。但是.append()呢?每次连接都使用String.concat()是否合适?或者只是变量,文字可以附加.append()

.concat()

针对这些情况,最佳做法和表现的一般规则是什么?我的假设在StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA") .append(B_String.concat("CCCCCCCCCCC")).append(D_String .concat("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE") .concat("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); 上是否正确,它应该真的不被使用?

9 个答案:

答案 0 :(得分:174)

+运算符

String s = s1 + s2

在幕后,这被翻译成:

String s = new StringBuilder(s1).append(s2).toString();

想象一下,如果你有s1 + s2,它会增加多少额外工作:

stringBuilder.append(s1 + s2)

而不是:

stringBuilder.append(s1).append(s2)

+

的多个字符串

值得注意的是:

String s = s1 + s2 + s3 + ... +sN

被翻译为:

String s = new StringBuilder(s1).append(s2).append(s3)...apend(sN).toString();

concat()

String s = s1.concat(s2);

String创建的char[]数组可以同时适合s1s2。将s1s2内容复制到此新数组。实际上,+运营商需要的工作量更少。

StringBuilder.append()

维护一个在需要时增长的内部char[]数组。如果内部足够大,则不会创建额外的char[]

stringBuilder.append(s1.concat(s2))

也表现不佳,因为s1.concat(s2)会创建一个额外的char[]数组并将s1s2复制到它,只是为了将新数组内容复制到内部StringBuilder } char[]

据说你应该一直使用append()并附加原始字符串(你的第一个代码片段是正确的)。

答案 1 :(得分:14)

编译器优化+连接。

所以

int a = 1;
String s = "Hello " + a;

转化为

new StringBuilder().append("Hello ").append(1).toString();

有一个很好的主题here解释了为什么要使用+运算符。

答案 2 :(得分:3)

优化由编译器自动完成。

Java2编译器将自动转换以下内容:

String s = s1 + s2; 

String s = (new StringBuffer()).append(s1).append(s2).toString();

直接摘自Oracles网站上的Java Best Practices

答案 3 :(得分:2)

您应始终使用append

concat创建一个新字符串,因此我觉得它很像+

如果您concat或使用+和2个最终字符串,JVM可以进行优化,这与在这种情况下的追加相同。

答案 4 :(得分:1)

如果连续两个字符串连接使用String.concat(通过创建一个适合两个字符串并将两个字符串的char数组复制到其中的新字符数组来创建一个新字符串。)

如果你在一行中连接多个(两个以上)字符串,使用+或StringBuilder.append,这没关系,因为编译器会将+转换为StringBuilder.append。这对多个字符串很有用,因为它维护了一个根据需要增长的char数组。

如果在多行上连接多个字符串,请创建一个StringBuilder并使用append-method。最后,当你完成将String附加到StringBuilder时,使用它的.toString() - 方法来创建一个String。 对于多行中的连接,这比第二种方法更快,因为第二种方法会在每一行上创建一个新的StringBuilder,附加字符串然后强制转换为String,而第三种方法只对整个事物使用一个StringBuilder。 / p>

答案 5 :(得分:0)

使用+运算符是最佳做法,它也简单易读。

  

Java语言为字符串提供特殊支持   连接运算符(+),以及将其他对象转换为   字符串。字符串连接是通过实现的   StringBuilder(或StringBuffer)类及其追加方法。

官方文件:iterator

答案 6 :(得分:0)

在字节代码级别没有什么不同,我们不会影响那里的效率。在执行字节代码级别的情况下,它必须通过调用append来执行+的非内联运算符重载方法。然后在汇编语言级别(Java用C和C编写产生类似于汇编的程序集,在堆栈中会有额外的寄存器调用store +方法调用,并且会有额外的推送。(实际上,交叉编译器可能会优化+运算符)打电话,在这种情况下,使它与效率没有区别。)

有一种方法可以提高可读性,这是一种很好的做法。 :)

答案 7 :(得分:0)

我个人更喜欢Strings.format(),简单易懂的单行string formatter

String b = "B value";
String d = "D value";
String fullString = String.format("A %s C %s E F", b, d);
// Output: A B value C D value E F

答案 8 :(得分:0)

所有答案都很好,而且可以解释。但是我觉得探索其他字符串连接技术也会有所帮助,例如-Guava Joiner,Streams,String.format等。

有关每种串联技术java-string-concatenation-which-way-is-best的性能的完整详细信息。

简而言之,串联性能随否而变化。要连接的字符串。例如,要串联1-10个字符串,这些技术最有效-StringBuilder,StringBuffer和Plus运算符。 为了连接100多个字符串-Guava Joiner,apache的stringsUtils库也很好用。

请浏览上述博客。它确实很好地解释了性能效率。

谢谢。