89

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

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

这是这样做的方法吗?从这篇文章中,我注意到+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"));

处理这些情况的最佳实践和性能的一般规则是什么?我的假设是否正确+,它真的不应该被使用吗?

4

9 回答 9

187

+操作员

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[]可以同时适合s1和的数组s2。复制s1s2内容到这个新数组。实际上比+操作员需要更少的工作。

StringBuilder.append()

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

stringBuilder.append(s1.concat(s2))

性能也很差,因为s1.concat(s2)创建了一个额外的char[]数组并复制s1s2它只是为了将新数组内容复制到 internal StringBuilder char[]

话虽如此,您应该append()一直使用并附加原始字符串(您的第一个代码片段是正确的)。

于 2012-04-09T20:00:29.110 回答
16

编译器优化 + 连接。

所以

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

被转化为

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

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

于 2012-04-09T19:57:50.713 回答
3

优化由编译器自动完成。

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

String s = s1 + s2; 

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

直接取自Oracles 网站上的Java 最佳实践。

于 2014-05-12T19:41:16.390 回答
2

您应该始终使用append.

concat创建一个新的字符串,所以它就像+我想的那样。

如果您concat或使用+2 final String JVM 可以进行优化,因此在这种情况下与进行追加相同。

于 2012-04-09T19:58:25.850 回答
1

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

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

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

于 2014-01-27T10:03:19.233 回答
1

我个人更喜欢Strings.format()简单易读的单行字符串格式化程序

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
于 2020-03-01T06:14:30.560 回答
0

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

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

官方文档:https ://docs.oracle.com/javase/8/docs/api/java/lang/String.html

于 2016-08-10T03:34:26.193 回答
0

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

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

于 2017-09-26T14:26:21.307 回答
0

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

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

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

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

谢谢。

于 2020-08-02T11:45:33.683 回答