When to use StringBuilder in Java
If you use String concatenation in a loop, something like this,
String s = "";
for (int i = 0; i < 100; i++) {
s += ", " + i;
}
then you should use a StringBuilder
(not StringBuffer
) instead of a String
, because it is much faster and consumes less memory.
If you have a single statement,
String s = "1, " + "2, " + "3, " + "4, " ...;
then you can use String
s, because the compiler will use StringBuilder
automatically.
In Java, when should I prefer String over StringBuilder vice versa?
You should use String
, because String
objects are cached in an object pool and might deliver better performance when you don't change them.
A StringBuilder
is only useful when you keep on concatenating String
tokens, which shouldn't be the case in a well normalized database table.
The JVM does all sorts of optimizations and chances are that even if you use concatenation the JVM might rewrite that routine to a StringBuilder
version.
When should you explicitly use a StringBuilder?
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.
When to use StringBuilder?
I warmly suggest you to read The Sad Tragedy of Micro-Optimization Theater, by Jeff Atwood.
It treats Simple Concatenation vs. StringBuilder vs. other methods.
Now, if you want to see some numbers and graphs, follow the link ;)
StringBuilder vs String concatenation in toString() in Java
Version 1 is preferable because it is shorter and the compiler will in fact turn it into version 2 - no performance difference whatsoever.
More importantly given we have only 3
properties it might not make a
difference, but at what point do you
switch from concat to builder?
At the point where you're concatenating in a loop - that's usually when the compiler can't substitute StringBuilder
by itself.
How to use stringBuilder
To prevent writing the same (partial) string literal multiple times, you can:
Use a constant for the common part:
if (CollectionUtils.isEmpty(primaryPathList)) {
final String COMMON = "Customer Hierarchy is mandatory field";
if (salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)) {
return Optional.of(COMMON + " for HebToYou.");
} else {
return Optional.of(COMMON + ".");
}
}Build the string using
StringBuilder
:if (CollectionUtils.isEmpty(primaryPathList)) {
StringBuilder buf = new StringBuilder("Customer Hierarchy is mandatory field");
if (salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)) {
buf.append(" for HebToYou");
}
return Optional.of(buf.append('.').toString());
}
Personally, I would keep the code in the question, especially if you ever might need support non-English versions of the text, because in other languages the extra text might not go there.
Should one use StringBuilder in a recursive function?
You can add StringBuilder to recursive method:
public String recursive(int n, StringBuilder sb) {
String retStr = "s";
if (n==0) {
return retStr;
}
else {
return sb.append(retStr).append(recursive(n-1, sb)).toString();
}
}
and call it
recursive(100, new StringBuilder());
Append String directly or use StringBuilder
As a programmer we should always care about the readability of our code and the first case looks quite readable to me than the second one.
Now if your question is which one should I choose ?
Than answer is any of them and you should not bother for this.StringBuilder
only make difference with loop, other than that currently both of the cases would be almost same.
when to use string over stringbuilder/stringbuffer?
A String offers more functionalities than a StringBuilder. The sole purpose of a StringBuilder, as its name implies, is to build a String.
A String is not less efficient than a StringBuilder (don't know where you got that). It is actually much more efficient, because since it's immutable, you can sefely share references without needing defensive copies.
And most importantly: performance is usually not the main concern anyway. What matters more is correctness, readability, safety, maintainability. And using an immutable String increases all these factors.
If String is so much better than a StringBuilder, then why do we have a StringBuilder? Because there is one use-case where using a StringBuilder is much more efficient than using a String: constructing a String by repeatedly appending parts:
String s = "";
for (String part: collection) {
s += part;
}
The above code is slow because many temporary String objects are created and copied, and must then be GCed. In that case, use a StringBuilder:
StringBuilder builder = new StringBuilder();
for (String part: collection) {
builder.append(part);
}
String s = builder.toString();
Related Topics
Gson: How to Exclude Specific Fields from Serialization Without Annotations
Illegalargumentexception or Nullpointerexception For a Null Parameter
Android Recyclerview Addition & Removal of Items
Foreign Key Constraints in Android Using SQLite? on Delete Cascade
Select Random Document from Firestore
Why Does Reading from Process' Inputstream Block Altough Data Is Available
Java App Behind Proxy to Use Http_Proxy Variable in Linux
Decibel Values at Specific Points in Wav File
In Java, "5/0" Statement Doesn't Fire Sigfpe Signal on My Linux MAChine, Why
Why How to Successfully Move a File in Linux While It Is Being Written To
Remote Debugging a Java Application
How to Check the Jdk Version Used to Compile a .Class File
How to Unzip Files Programmatically in Android
Android Download Binary File Problems
Android: Difference Between Onintercepttouchevent and Dispatchtouchevent
Arval SQLexception: Fatal: Sorry, Too Many Clients Already in Postgres
Force Jvm to Do All Io Without Page Cache (E.G. O_Direct)
Which Operating Systems Support Native (Inotify-Like) File Watching in Java