I created a StringBuilder object without any value and appended some values afterwards. I later wanted to replace the object with an entirely different string.
Here's the code:
StringBuilder finalVersion = new StringBuilder();
finalVersion.append("6.0")
for (int i = 0; i < list.length(); i++) {
if(/*...*/){
finalVersion.append(".2");
} else {
finalVersion.append(".1");
}
if (/*...*/) {
if (/*...*/) {
finalVersion = new StringBuilder("Invalid parameter"));
}
}
}
What I've done is I created a new object to change the value, but perhaps there is a better approach without using stringBuilder.setLength(0);
.
Could someone help?
To solve it I created a new object to change the value but I guess there is a better approach without use
sb.setLength(0)
Both of those are good approaches. Another is sb.delete(0, sb.length())
.
And when you want to replace the existing string content, sb.replace(0, sb.length(), "new content")
is another option.
It really depends what your goal is:
Calling new StringBuffer(...)
will give you a freshly allocated object with either the default capacity or a capacity that you specify.
The setLength
, delete
and replace
approaches will recycle the existing object. This has advantages and disadvantages.
On the plus side, you don't allocate a new object1 ... so less garbage.
On the minus side, the string buffer uses the same amount of space as before, whether or not it needs to. Also, if you do this repeatedly, the chances are that the buffer and its backing array will be tenured by the GC, adding to the long-term memory load. You can free the unused capacity by calling sb.trimToSize()
, but that is liable to cause a reallocation; i.e. what you were trying to avoid by not using new
.
My advice would be to use new
unless either the context means that you
can't, or your profiling tells you that new
is generating too much garbage.
Looking at the code2, I think that setLength
should be marginally faster than delete
for emptying a StringBuffer
. It gets more complicated when you are replacing the contents with new contents. Now you are comparing
sb.setLength(); sb.append("new content");
versus
sb.replace(0, sb.length(), "new content");
It needs to be measured ... if you care enough3 about performance to be comparing the cases.
1 - Unless the replacement string is large enough that the buffer needs to grow to hold it.
2 - By my reading of various versions of the StringBuilder
and AbstractStringBuilder
code, the delete
method will always call System.arraycopy
. However, to understand the performance impact, one would need to benchmark this carefully for different sizes of StringBuilder
and across different Java versions.
3 - Actually, if you need to care. Beware the evils of premature optimization.