可能是我分裂头发,但我想知道以下情况:
String newString = a + b + c; //case 1
String newString = a.concat(b).concat(c); //case 2
StringBuilder newString = new StringBuilder(); //case 3
newString.append(a);
newString.append(b);
newString.append(c);
哪个最好用?
我的意思是任何方式。
阅读这些内容,其他帖子说案例3不是最佳表现,其他案例1案例3最终会出现在案例3等中。
更具体一点。
例如,将所有内容放在一边,如果你必须维护他的代码,哪种风格更适合从另一个程序员那里看到它?
或者您认为哪种编程效率更高? 或者你会认为更快等等。
我不知道如何表达这一点。
答案如:案例3可以更快,但绝大多数程序员更喜欢案例1,因为如果它在某种程度上得到了详细阐述,它也是最可读的
答案 0 :(得分:22)
案例1简洁明了,表达了意图,相当于案例3.
案例2的效率较低,而且可读性较差。
案例3几乎与案例1一样有效,但更长,更不易读。
使用案例3只有在必须在循环中连接时才能使用。否则,编译器将情况1编译为情况3(除了它使用new StringBuilder(a)
构造StringBuilder),这使得它比你的情况3)更有效。
答案 1 :(得分:7)
案例3是性能最高的形式,但JVM将案例1转换为案例3。
但我认为案例2是最差的,它不像案例1那样可读,而不像案例3那样。
如果你想在一个循环中连接字符串只是用例3,你可以很容易地测试性能增益,但是如果它不在一个循环中(或者你没有在一个序列中附加大量字符串)它们几乎是相同。
您不应使用+运算符的情况为:
String a = "";
for (String x : theStrings) {
a += x;
}
或
String a = b + c;
a = a + d;
a = a + e;
a = a + f;
答案 2 :(得分:2)
案例3在大多数方面都更好。在案例3中,您不会最终创建3个字符串对象。由于字符串不变性,2将为每个+(或)concat创建字符串对象的开销。
编辑:重新阅读文件并同意大多数评论,案例1是案例3。
答案 3 :(得分:1)
对于简单的情况,使用+
显然更具可读性。
对于罕见的更复杂的案例,StringBuilder
是有道理的。如果您要跨行分割,那么+
很快就会成为性能阻力。循环从O(n)性能变为O(n ^ 2) - 如果 n 很小则不成问题,但如果 n 在尴尬的情况下可能很大则是一个大问题(可能是在做一些关键的事情,或者某人是恶意的时候)。
与其他答案相反,如果您只有三个字符串,则concat
可能是性能优胜者。我是精神病吗?不。考虑其他两个选项。您正在创建一个带有数组的StringBuilder
对象。附加字符串可能需要更换数组,并且您可能在数组的末尾留下奇数位(这是分配的特定粒度,因此一些额外的char
可能会或可能不会增加内存使用量) 。如果您讨厌读取代码的每个人,您可以计算必要的容量。最好的情况,两个数组(一个用于StringBuilder
,一个用于String
(过去八年没有共享))每个结果文本的大小和另外两个对象(StringBuilder
和String
)。现在,对于concat
,您将分配给具有两个数组的String
个对象,但第一个数组将更短c.length()
。这是一场胜利!好吧,不是为了可读性。
免责声明:JVM可以进行疯狂优化,包括转义分析后的堆栈分配和核心类的特殊大小写。与手工混淆的代码相比,它们更有可能优化常见和简单的代码。
答案 4 :(得分:0)
在使用JDK 1.8进行性能分析时,我发现案例2是性能方面的赢家。
class Solution {
public static void main(String[] args) {
String s ="ABC", s1 = "", s2 = "", s3 = "";
long t1 = System.nanoTime();
for(int i = 1; i < 11; i++) {
s1 = s1 + s;
}
System.out.println(System.nanoTime() - t1);
System.out.println(s1);
long t2 = System.nanoTime();
for(int i = 1; i < 11; i++) {
s2 = s2.concat(s);
}
System.out.println(System.nanoTime() - t2);
System.out.println(s2);
long t3 = System.nanoTime();
StringBuilder sb = new StringBuilder();
for(int i = 1; i < 11; i++) {
sb.append(s);
}
s3 = sb.toString();
System.out.println(System.nanoTime() - t3);
System.out.println(s3);
}
}
结果:
40615
ABCABCABCABCABCABCABCABCABCABC
9157
ABCABCABCABCABCABCABCABCABCABC
20243
ABCABCABCABCABCABCABCABCABCABC
答案 5 :(得分:0)
除上述内容外,在JEP 280下仅针对字符串连接 进行了显着的性能改进。
请参阅 https://openjdk.java.net/jeps/280 和解释 https://dzone.com/articles/jdk-9jep-280-string-concatenations-will-never-be-t
简而言之,这意味着从Java 9 "Hello " + "world"
字符串连接是甚至考虑性能的首选方式。