最佳实践/性能:将StringBuilder.append与String.concat混合
我想了解最佳实践是什么,为什么连接string文字和variables的不同情况。 例如,如果我有这样的代码
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA") .append(B_String).append("CCCCCCCCCCC").append(D_String) .append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE") .append("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
这是做到这一点的方法吗? 在这篇文章中 ,我注意到Strings上的+
运算符创build了一个新的StringBuilder实例,连接操作数,并返回一个string转换,这似乎比调用.append()
更多的工作。 所以如果这是真的,那么这是不可能的。 但是String.concat()
呢? 每个连接使用.append()
是否正确? 或者只是为variables,和文字可以附加.concat()
?
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA") .append(B_String.concat("CCCCCCCCCCC")).append(D_String .concat("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE") .concat("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
关于这些情况的最佳实践和性能的一般规则是什么? 我的假设是正确的,它应该真的不被使用?
+
运营商
String s = s1 + s2
在幕后,这被翻译成:
String s = new StringBuilder(s1).append(s2).toString();
想象一下,如果你在这里有s1 + s2
多加多余的工作:
stringBuilder.append(s1 + s2)
代替:
stringBuilder.append(s1).append(s2)
多个string+
值得注意的是:
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
创build可以适合s1
和s2
char[]
数组。 将s1
和s2
内容复制到这个新数组中。 其实要求+
运营商less工作。
StringBuilder.append()
维护一个内部char[]
数组,在需要时增长。 如果内部足够大,则不会创build额外的char[]
。
stringBuilder.append(s1.concat(s2))
也是performance不佳,因为s1.concat(s2)
创build一个额外的char[]
数组并将s1
和s2
复制到它只是为了将新的数组内容复制到内部StringBuilder
char[]
。
这就是说你应该始终使用append()
并追加原始string(你的第一个代码片段是正确的)。
编译器优化+级联。
所以
int a = 1; String s = "Hello " + a;
被转换成
new StringBuilder().append("Hello ").append(1);
这里有一个很好的主题,解释为什么你应该使用+运算符。
你应该总是使用append
。
concat
创build一个新的string,所以它很像+
我想。
如果你concat
或使用+
最后一个String的话,JVM就可以进行优化,所以和在这种情况下进行追加一样。
优化是由编译器自动完成的。
Java2编译器将自动转换以下内容:
String s = s1 + s2;
至
String s = (new StringBuffer()).append(s1).append(s2).toString();
直接从Java最佳实践 Oracles网站。
如果你连接两个string,使用String.concat(创build一个新的string,创build一个新的字符数组,适合两个string和string的char数组)。
如果你在一行中串联多个(多于两个)string,使用+或者StringBuilder.append,这是没关系的,因为编译器把+转换成StringBuilder.append。 这对于多个string是很好的,因为它维护一个根据需要增长的字符数组。
如果您通过多行连接多个string,请创build一个StringBuilder并使用append-method。 最后当你完成将string附加到StringBuilder时,使用它的.toString() – 方法来创build一个string。 因为第二种方法会在每一行上创build一个新的StringBuilder,将string附加到string,然后再转换回string,而第三个方法只使用一个StringBuilder。
使用+
操作符是最佳实践,它也简单易读。
Java语言为string连接运算符(+)提供特殊支持,并将其他对象转换为string。 string连接是通过StringBuilder(或StringBuffer)类及其附加方法实现的。
官方文档: https : //docs.oracle.com/javase/8/docs/api/java/lang/String.html
在字节代码级别没有什么不同,我们并没有妥协有效性那里。 在执行字节码级别的情况下,通过调用append必须通过+的非内联运算符重载方法。 那么在汇编语言层面(Java是用C和C编写的,与汇编相似的汇编语言,将会有额外的注册调用来存储堆栈中的方法调用,并且会有额外的推送)(实际上,交叉编译器可能会优化+运算符在这种情况下,通话效率并不差。)
有一个方法来提高可读性是一个很好的做法。 🙂