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

Nic*_*ndo 82 java string stringbuilder string-concatenation

我试图了解最佳实践是什么以及为什么连接不同情况下的字符串文字和变量.例如,如果我有这样的代码

StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
    .append(B_String).append("CCCCCCCCCCC").append(D_String)
    .append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
    .append("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
Run Code Online (Sandbox Code Playgroud)

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

StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
    .append(B_String.concat("CCCCCCCCCCC")).append(D_String
    .concat("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
    .concat("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
Run Code Online (Sandbox Code Playgroud)

针对这些情况的最佳实践和表现的一般规则是什么?我的假设是否正确+,它应该真的不被使用?

Tom*_*icz 177

+ 操作者

String s = s1 + s2
Run Code Online (Sandbox Code Playgroud)

在幕后,这被翻译为:

String s = new StringBuilder(s1).append(s2).toString();
Run Code Online (Sandbox Code Playgroud)

想象一下,如果你在s1 + s2这里有多少额外的工作:

stringBuilder.append(s1 + s2)
Run Code Online (Sandbox Code Playgroud)

代替:

stringBuilder.append(s1).append(s2)
Run Code Online (Sandbox Code Playgroud)

多个字符串 +

值得注意的是:

String s = s1 + s2 + s3 + ... +sN
Run Code Online (Sandbox Code Playgroud)

被翻译成:

String s = new StringBuilder(s1).append(s2).append(s3)...apend(sN).toString();
Run Code Online (Sandbox Code Playgroud)

concat()

String s = s1.concat(s2);
Run Code Online (Sandbox Code Playgroud)

String创建char[]可以兼顾s1和的数组s2.复制s1s2内容到这个新数组.实际上需要较少的工作然后+运营商.

StringBuilder.append()

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

stringBuilder.append(s1.concat(s2))
Run Code Online (Sandbox Code Playgroud)

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

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

  • 虽然较新版本的编译器会自动将+运算符优化为字符串构建器,但是假设它不像旧版本那样不一定是好事.在整个讨论中有一个非常重要的主题被忽略,这实际上是StringBuilder(字符串池)的主要目的之一.使用字符串构建器将所有内容保存为char [],并且在编译器优化之前不会像+运算符那样创建中间字符串(用于执行连接).使用concat创建一个缓存但未使用的中间String对象. (11认同)
  • _Effective Java 2-nd edition _:__重复使用字符串连接运算符来连接n个字符串需要时间二次n .__那么它仍然相关吗? (3认同)

小智 15

编译器优化+连接.

所以

int a = 1;
String s = "Hello " + a;
Run Code Online (Sandbox Code Playgroud)

变成了

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

这里有一个很好的主题,解释了为什么你应该使用+运算符.

  • 编译器实际上会将其优化为`String s ="Hello World";`因为你使用文字. (3认同)