我认为这是最有效的字符串拼接方法。
StringBuilder的缓冲区在此处创建,其容量足以容纳其中的所有字符串,否则StringBuilder可能需要将缓冲区扩展3倍。
但是当我编译/反编译这个东西时
new StringBuilder(s1.length() + s2.length() + s3.length()).append(s1).append(s2).append(s3).toString();
StringBuilder的缓冲区在此处创建,其容量足以容纳其中的所有字符串,否则StringBuilder可能需要将缓冲区扩展3倍。
但是当我编译/反编译这个东西时
String s4 = s1 + s2 + s3;
我得到了由javac(1.7.0_03)构建的实际代码,如下所示:
String s4 = (new StringBuilder(String.valueOf(s1))).append(s2).append(s3).toString();
哪种方式更有效?
更新
正如Steven Schlansker所建议的那样,这里有一个性能测试。
String s1 = "0123456789";
String s2 = s1 + s1 + s1;
String s3 = s1 + s1 + s1 + s1 + s1 + s1;
long t0 = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
String s4 = new StringBuilder(s1.length() + s2.length() + s3.length()).append(s1).append(s2).append(s3).toString();
// String s4 = s1 + s2 + s3;
}
System.out.println(System.currentTimeMillis() - t0);
虽然不完美,但结果表明我的版本速度比原版快了约30%。在我的笔记本电脑(Celeron 925)上,对于版本1,它提供了大约230毫秒的时间,而对于版本2,则为大约300毫秒。实际上,这是我预期的结果。因此,我认为如果javac以更高效的方式编译字符串连接,那将是一个好主意。有足够的类似代码行。
return "\\Q" + s + "\\E";
即使在JDK类中也是如此。最后一行来自java.util.Pattern,它是为了效率而设计的。
Pattern.compile(s, Pattern.LITERAL);
。这样只需要针对每个字符串s
执行一次,避免了创建StringBuilder和解析字符串的过程。 - Peter Lawrey