可能重复:
StringBuilder vs String concatenation in toString() in Java
为什么StringBuilders比普通的String Concatenation更好用?
答案 0 :(得分:8)
这些天的java编译器非常聪明,无论如何都会使用StringBuilder来连接字符串。
这使以下代码相同
System.out.println("test = "+test+" test2 = "+test2);
System.out.println((new StringBuilder()).append("test = ").append(test).append("test2 = ").append(test2).toString());
因此,如果你的字符串落在一个可执行行上,你就不应该害怕使用字符串连接。
但是,如果你循环遍历一些东西并将字符串连接在一起,那么java运行时将创建所有这些新的StringBuilder,然后将它们连接在一起,因此在这种情况下提供你自己的StringBuilder单个实例更有效率< / p>
StringBuilder sb = new StringBuilder();
for(String test : testStrings) {
sb.append(" ").appendtest);
}
答案 1 :(得分:2)
因为字符串是不可变的。当您进行字符串连接时,您可以创建许多字符串作为临时值,然后必须进行垃圾回收。使用StringBuilder,有一个潜在的可变数据结构,所以你只需继续使用它。
效果是限制GC的数量并减少执行的JVM指令的数量。说明通常通常是个大问题,但我发现字符串连接的错误用法会将JVM推入大规模的GC加载。
答案 2 :(得分:1)
StringBuilder是可变的,因此您不会创建新的字符串。
答案 3 :(得分:1)
StringBuilder不会在连接,子串e.t.c等操作中在池中创建新的字符串。简而言之,每次对String进行操作时,都会在池中创建一个新的String。
String x = "abc"
x= x+"def";
因此在池中创建了三个字符串。 “abc”,“def”。 “abcdef”..... StringBUilder只使用一个对象时可以完成同样的任务。
建议使用StringBuilder而不是StringBuffer,因为StringBuffer是线程安全的并且具有同步方法,因此除非需要线程安全,否则建议使用stringbuilder,因为字符串缓冲区可能会导致性能开销,但可以忽略不计。
答案 4 :(得分:1)
我决定通过YourKit Java Profiler运行3个简单的测试用例,将您的问题提交到'profiler'测试。我使用String,StringBuilder和StringBuffer执行了三次测试。
每个的来源如下:
public void testString() throws Exception {
for ( int x = 0; x < 10000000; x++ ) {
String s = "the quick brown fox jumped over the lazy dogs. ";
for ( int i = 0 ; i < 5; i++ ) {
s += s;
}
}
}
public void testStringBuilder() throws Exception {
for ( int x = 0; x < 10000000; x++ ) {
StringBuilder s = new StringBuilder("the quick brown fox jumped over the lazy dogs. ");
for ( int i = 0 ; i < 5; i++ ) {
s.append(s);
}
}
}
public void testStringBuffer() throws Exception {
for ( int x = 0; x < 10000000; x++ ) {
StringBuffer s = new StringBuffer("the quick brown fox jumped over the lazy dogs. ");
for ( int i = 0 ; i < 5; i++ ) {
s.append(s);
}
}
}
这些测试用例中的每一个都是在64位JDK1.6_27上启用“跟踪”的情况下执行的。以下是每次测试的时间结果(抱歉,由于SO限制而不得不删除图像,而是发布CSV输出)。
首先要注意的是,在String和StringBuffer测试中,JVM使用StrinbBuffers作为内部实现。但是,在String情况下,整体性能要差得多。差异的关键在于调用计数。
在String情况下,使用连接运算符(“+ =”)会导致创建两个StringBuffer实例(请参阅“调用计数”结果:99M对48M)。
因此,如果您要进行大量连接,请直接使用StringBuffer。
字符串:
"Name","Time (ms)","Avg. Time (ms)","Own Time (ms)","Invocation Count","Level"
"com.altosresearch.utils.test.StringsTest.testString()","190497","190497","0","1", "7"
"java.lang.StringBuilder.append(String)","117742","0","117742","99825142", "8"
"java.lang.StringBuilder.toString()","46142","0","46142","49912563", "8"
"java.lang.StringBuilder.<init>()","26612","0","26612","49912563", "8"
的StringBuilder:
"Name","Time (ms)","Avg. Time (ms)","Own Time (ms)","Invocation Count","Level"
"com.altosresearch.utils.test.StringsTest.testStringBuilder()","90179","90179","0","1", "7"
"java.lang.StringBuilder.append(CharSequence)","79212","0","79212","48924577", "8"
"java.lang.StringBuilder.<init>(String)","10966","0","10966","9784916", "8"
的StringBuffer:
"Name","Time (ms)","Avg. Time (ms)","Own Time (ms)","Invocation Count","Level"
"com.altosresearch.utils.test.StringsTest.testStringBuffer()","83518","83518","0","1", "7"
"java.lang.StringBuffer.append(StringBuffer)","73207","0","73207","48694049", "8"
"java.lang.StringBuffer.<init>(String)","10311","0","10311","9738810", "8"
答案 5 :(得分:0)
由于字符串是不可变的,如果要更改代码中的String,可能需要使用StringBuilder类。
答案 6 :(得分:0)
String是不可变的,因此每个concat都会创建一个新对象,Stringbuffer / builder是可变的。提供了一条说明at this link