When should you explicitly use a StringBuilder? [duplicate] - java

This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
String concatenation in Java - when to use +, StringBuilder and concat [duplicate]
(9 answers)
Closed 8 years ago.
As I understand it, when I do String baz = "foo" + "bar" + "123" the Java compiler internally replaces the expression with a StringBuilder. However our Java teacher told us that it is good practice to always use a StringBuilder explicitly...
Am I correct in assuming I will only need to explicitly use StringBuilder when concatenating inside loops as indicated in an answer to Stack Overflow question String builder vs string concatenation? Are there other cases where you should explicitly use a StringBuilder instead of + or +=?

It's more general than "inside loops" - it's any time you want to do concatenation over multiple statements, and don't need the intermediate result as a string. For example:
StringBuilder builder = new StringBuilder("Start");
if (someCondition) {
builder.append("Foo");
}
if (someOtherCondition) {
builder.append("Bar");
}
builder.append("End");
String result = builder.toString();
While you could write that as:
String result = "Start" + (someCondition ? "Foo" : "")
+ (someOtherCondition ? "Bar" : "") + "End";
... that becomes hard to read. And if there are more statements within the if bodies, it may not even be feasible.
To correct something within your question though:
As I understand it, when I do String baz = "foo" + "bar" + "123" the java compiler internally replaces the expression with a StringBuilder.
No, when you write that expression the compiler recognizes that it's a compile-time constant, and replaces it with
String baz = "foobar123";
That's a very good reason not to explicitly use a StringBuilder - the code above is clearly more efficient at execution time than
String baz = new StringBuilder("foo").append("bar").append("123").toString();
When it isn't a compile-time constant, the Java compiler will perform the concatenation using a StringBuilder, usually leaving you with easier-to-understand code than with the explicit use of StringBuilder, but with no performance hit. I suspect your teacher either doesn't properly understand string concatenation, or simply read somewhere else that you should use StringBuilder without fully understanding when it's appropriate.

Obi Wan has said that only Sith thinks in absolutes or something similar...
It's good you know that Java compiler internally replaces "+" on Strings with the usage of the StringBuilder. This is what are the compilers for: to make the life easier.
Unless you have loops, as in linked case, or conditionals from Jon Skeet's example, it's primarily the matter of readibility and the ease of maintanance.
Replacing
return "User " + userName + " said";
with
new StringBuilder().append("User ").append(userName).append(" said").toString();
makes the code longer, probably harder to modify, is more likely to force line breaks, and gives you more performance.
However, when the addition apply not only to the strings, but there are numbers involved, probably the solution with StringBuilder sometimes may be more readable.
return "User" + a + b + " said: " + (c + d);
may be more confusing as:
return new StringBuilder().append("User ").append(a).append(b)
.append(" said: ").append(c+d).toString();
But it's primarily the matter of opinion and coding style. "Should" is not a good word here.

They're also good for implementing things like C#'s 'out' keyword with a String. Example
public int getInt(StringBuilder error)
{
int retVal = 0;
if (someErrorOccured)
error.append("Couldn't get int because of...");
else
retVal = whatItsSupposedToBe;
return retVal;
}

Related

When is the + operator faster than a StringBuilder? [duplicate]

This question already has answers here:
StringBuilder/StringBuffer vs. "+" Operator
(4 answers)
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 8 years ago.
In the past, I have been lead to believe that you should use StringBuilder and append(String) when building a string with variables, as opposed to string += split[i]. In what cases is this accurate? I ask because normally, if I was to write the following:
String[] split = args; // command line arguments or whatever
String myString = "";
for (int i = 0; i < split.length; i++) {
myString += split[i];
}
I am told by my IDE that it should be converted to use a StringBuilder instead. However, writing something like this:
StringBuilder build = new StringBuilder();
build.append("the ").append(build.toString()).append(" is bad").append(randomvar);
build.toString();
IntelliJ actually lists as a performance issue using a StringBuilder when I should be using a String. The fact that it's listed as a performance issue would indicate it could actually cause problems as opposed to just being a tiny bit slower.
I did notice that the first example is a loop and the second isn't - is a StringBuilder recommended for lots of concatenations but normal concatenation is better for non-looping situations (this also means in a loop the operator += would be used, whereas outside of a loop it could be "the " + build.toString() + " is bad" + randomVar - is += the problem as opposed to +?)
String concatenations are converted into calls to StringBuilder.append() behind the scenes.
String literal concatenations are (or at least can be) converted to individual String literals.
You're presumably using a String variable (not just two literals) inside the loop, so Java can't just replace that with a literal; it has to use a StringBuilder. That's why doing String concatenations in a loop should be done using a single StringBuilder, otherwise Java ends up creating another instance of StringBuilder every time the loop iterates.
On the other hand, something like this:
String animals = "cats " + "dogs " + "lizards ";
Will (or can be) replaced (by Java, not you) with a single String literal, so using a StringBuilder is actually counter-productive.
Beginning in java 1.5, the String + operator is translated into calls to StringBuilder.
In your example, the loop should be slower because the + operator creates a new StringBuilder instance each time through the loop.
The compiler will actually turn them both into the same form before compiling so neither will result in any performance difference. In this scenario you want to go with the shortest and most readable method available to you.
"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."
Source: http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.18.1.2
For little concats you can use the + operator with none issue. StringBuffer is indicated when we have large strings to be concatened, so with this class you can save memory and processor's time as well.
You can make a test trying to concat 1 million of words using + operator, and run the same teste using StringBuffer to see the different by yourself.

Java - how many string concat's should prompt the use of StringBuilder? [duplicate]

This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 9 years ago.
I understand that StringBuilder should be used for concatenating multiple strings rather than using +. My question is what is the cut off point?
I have been told that if concatenating 4 or more strings you should use the StringBuilder.append(), and for anything else, use +.
Is that the case? or is the point at which stringbuilder is more efficient more than 4?
As of Java 1.5, the compiler automatically uses StringBuilder when + is used in the source.
From the Javadoc for String:
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.
Zero.
Many years ago, in a Java version far far away (1.4), some people recommended replacing concatenation by StringBuffer (the thread-safe equivalent of StringBuilder, which had not been invented yet).
With the introduction of StringBuilder, and the redefinition of concatenation in terms of the faster StringBuilder, "optimized" code using StringBuffer incurred in unneeded synchronization, while non-optimal code with + was automatically enjoyed to the benefits of StringBuilder.
I would use StringBuilder when the concatenation is mixed with control structures or loops, or when I need to update some characters in the middle of the strings. Otherwise I assume that the compiler is smart enough to do a good job with the traditional concatenation.
Starting in jse 5, the + sign converts to a stringbuilder during compilation.
There is a caveat to this though, this:
String blam = a + b + c + d + e;
results in one stringbuilder and 5 appends (as expected)
This; however:
String blam = a;
blam += b + c;
blam := d + e;
results in 3 stringbuilders (one per line).
The point: + sign is fine, just stack it all in one line of code.
I would say that the compiler will substitute the plus with StringBuilder itself.
There are several situations you want to avoid in this case. For example using + in a loop. For each iteration a new StringBuilder will be created.
Might wanna read this question
The compiler is pretty good at optimizing this stuff, so usually, you won't gain much. But if you're doing concatenations in a loop for instance, you might gain some benefits from using a StringBuilder instead.
There is no defined answer because it's depends on JVM implementation. I use StringBuilder when I need to concat more than 3 strings.
I noticed a good case. When you need to concat static final String's you don't have to use StringBuilder. The compliler will concat it withour performance falling:
final class Example {
public static final String STRING_ONE = "string";
public static final String STRING_TWO = "string";
public static final String STRING_THREE = "string";
public static final String STRING_FOUR = "string";
public String getBigString() {
return STRING_ONE + STRING_TWO + STRING_THREE + STRING_FOUR;
}
}
Also I very interested in that question. I tryed to implement a good test and asked about that here.

String concatenation translated to stringbuilder in Java

I saw this question and some similar and I think it's not duplicate :
StringBuilder vs String concatenation in toString() in Java
Here is the deal, I hear a very clever work colleague of mine talking this morning about how java optimizes up to 8 or 16 string concatenation(I'm not sure at this point) to string builder. Because this might have been a vague description of what I mean here is an example of 6 String concatenation :
public String test(){
return "a" + "b" + "c" + "d" + "e" + "f";
}
So that this is actually translated to :
public String test(){
StringBuilder sb = new StringBuilder();
return sb.append("a").append("b").append("c").append("d").append("e").append("f").toString();
}
I had to leave the conversation earlier, is this true?If yes can someone provide more details of exact number up to when this optimization is done 8/16 or x?
I didn't know about this before I've heard it. good to know if true.
As per request, here my comment as answer to the question:
You can find a thorough explanation of how string concatenation works in Java in this blog post: http://znetdevelopment.com/blogs/2009/04/06/java-string-concatenation
I don't know about the exact number but generally you shouldn't worry about concatenating strings with the + operator, unless if the concatenation happens in the iteration of some loop, because that's the case where the compiler cannot optimize and you need to use StringBuilder explicitly, or even String.concat.
Which way is fastest depends also on whether your data is constant or variable. In your example the string would be concatenated at compile time to "abcdef".

Does "+" use in String concatenation affect efficiency? [duplicate]

This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
How Java do the string concatenation using "+"?
(6 answers)
Closed 8 years ago.
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?
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
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 Strings 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();
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.
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.
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.

append or + operator in StringBuffer?

In my project there are some code snippets which uses StringBuffer objects, and the small part of it is as follows
StringBuffer str = new StringBuffer();
str.append("new " + "String()");
so i was confused with the use of append method and the + operator.
ie the following code could be written as
str.append("new ").append("String()");
So are the two lines above same?(functionally yes but) Or is there any particular usage of them? ie performance or readability or ???
thanks.
In that case it's more efficient to use the first form - because the compiler will convert it to:
StringBuffer str = new StringBuffer();
str.append("new String()");
because it concatenates constants.
A few more general points though:
If either of those expressions wasn't a constant, you'd be better off (performance-wise) with the two calls to append, to avoid creating an intermediate string for no reason
If you're using a recent version of Java, StringBuilder is generally preferred
If you're immediately going to append a string (and you know what it is at construction time), you can pass it to the constructor
Actually the bytecode compiler will replace all string concatenation which involve non constants in a Java program with invocations of StringBuffer. That is
int userCount = 2;
System.out.println("You are the " + userCount + " user");
will be rewritten as
int userCount = 2;
System.out.println(new StringBuffer().append("You are the ").append(userCount).append(" user").toString());
That is at least what is observable when decompiling java class files compiled with JDK 5 or 6. See this post.
The second form is most efficient in terms of performance because there is only one string object that is created and is appended to the stringbuffer.
The first form creates three string objects 1) for "new" 2)for "new String" 3) for the concatenated result of 1) and 2). and this third string object is concatenated to the string buffer.
Unless you are working with concurrent systems, use StringBuilder instead of StringBuffer. Its faster but not thread-safe :)
It also shares the same API so its more or less a straight find/replace-

Categories