可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has an answer here:
-
StringBuilder vs String concatenation in toString() in Java
18 answers
-
How Java do the string concatenation using “+”?
6 answers
I have worked with String, StringBuilder and StringBuffer in java.
I thought of this question, while I was thinking from efficiency point of view.
Does "+" use in String concatenation affect efficiency?
回答1:
Yes, but so little it shouldn't matter most of the time.
Using '+' for string constants is the most efficient as the compiler can perform the concatenation.
If you are joining two Strings, the concat
method is the most efficient as it avoids using a StringBuilder.
There is almost never a good reason to use StringBuffer except for backward compatibility. StringBuilder or StringWriter are a better choice. However, it is still used explicitly more often than StringBuilder in the JDK :P
StringBuffer is dead, long live StringBuffer
回答2:
If you're concatenating in a single statement, then it won't matter since the compiler/JIT compiler will automatically optimize it using a StringBuilder
.
So "a"+b+"c"
will be optimized to (new StringBuilder("a").append(b).append("c")).toString()
However, if you're concatenating a large number of String
s in a loop, definitely explicitly use a StringBuilder
as it will significantly speed up your program.
String a = "";
for( int i = 0; i < 1000000; i++ )
a += i;
should be changed to
StringBuilder sb = new StringBuilder();
for( int i = 0; i < 1000000; i++ )
sb.append(i);
String a = sb.toString();
回答3:
A bit of Yes, But still NO
From the JLS, 15.18.1.2
Optimization of String Concatenation
An implementation may choose to perform conversion and concatenation
in one step to avoid creating and then discarding an intermediate
String object. To increase the performance of repeated string
concatenation, a Java compiler may use the StringBuffer class or a
similar technique to reduce the number of intermediate String objects
that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.
回答4:
In your example:
" Does +" + " use in String concatenation affect efficiency? "
we have to literal Strings, which might be replaced by the compiler, so this will be faster, than StringBuffer/append/toString.
But efficient/faster compared to what? Code execution? Code writing? Code reading?
Since reading a
"Foo = " + foo;
is very easy, I would recommend it, as long as it isn't repeated a million times, or a " s += s2;" repeated a hundret times.
Especially,
System.out.println ("Player " + n + " scores " + player[n].score);
is far better readable than
System.out.println (new StringBuffer ("Player ").append ((Integer.valueOf (n)).toString ().append (" scores ").append (...
Just avoid it in applications which need high performance, or concatenate a very large amount of strings, or a large amount recursively.
回答5:
Since strings are immutable, concatenating strings causes a string create. ie.. "A"+"B"+"C" causes the creation of "AB", then "ABC". If you're doing multiple concatenations it will always be more efficient to use a StringBuilder (not the older but api-identical StringBuffer, which has synchronization costs)
If you have a single line concatenation the compiler will do this for you if possible - that is, if you compile "A"+"B"+"C" you're likely to see, if you decompile, something like new StringBuilder("A").append("B").append("C").toString(). However the compiler can't optimize multiple string concats over multiple lines - i.e, if you have multiple concatenating lines, you're going to see something like the above on each lines, including the extra StringBuilder creation. Better to do it manually.
You can verify this for yourself by putting together a simple example and decompiling.
回答6:
If you are using multiple times concatenation with '+' , then yes to some extend. Coz
when you do String a + String b , it actually internally creates a StringBuffer object and use append() of StringBuffer. So every time you do a '+' a new temporary StringBuffer object gets created initialized with "a" and then appended with "b", which then gets converted to a string object.
So if you need multiple concatenation you should rather create a StringBuffer(thread-safe)/StringBuilder(not thread safe) object and keep appending, so that you avoid the creation of StringBuffer objects again and again.