Michael
Michael

Reputation: 9402

Does StringBuilder.toString retain the built string?

I'm creating a StringBuilder to collect strings that I periodically flush to a server. If the flush fails, I want to keep the strings to try again next time, although in the mean time I might get additional strings to send which must be added to the StringBuilder.

What I want to know is what the most efficient way to do this would be, as this is being done in an Android app where battery usage and thus CPU usage is a big concern. Does calling StringBuilder's toString() function store the resulting string it returns internally so that a subsequent call doesn't have to do the work of copying all the original strings over? Or if the call fails, should I create a new StringBuilder initialized with the return value from toString()?

Upvotes: 4

Views: 2956

Answers (3)

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

StringBuilder.toString API says that a new String object is allocated and initialized to contain the character sequence currently represented by this object.

Upvotes: 0

seand
seand

Reputation: 5286

It would be an implementation detail. Since java strings are immutable a correct impl can choose to share or create new strings from StringBuilder.toString() even if it's not needed.

As everyone says, you can test to see if this is indeed a real performance issue for you. If it is one (clunky) workaround is to wrap StringBuilder and cache the resulting string. You can use a dirty flag to indicate the content was modified.

Upvotes: 0

Tushar
Tushar

Reputation: 8049

Here is the OpenJDK source code for StringBuilder:

public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

The source for the String constructor with those parameters is:

public String(char value[], int offset, int count) {
    if (offset < 0) {
        throw new StringIndexOutOfBoundsException(offset);
    }
    if (count < 0) {
        throw new StringIndexOutOfBoundsException(count);
    }
    // Note: offset or count might be near -1>>>1.
    if (offset > value.length - count) {
        throw new StringIndexOutOfBoundsException(offset + count);
    }
    this.offset = 0;
    this.count = count;
    this.value = Arrays.copyOfRange(value, offset, offset+count);
}

So yes, it does create a new String everytime, and yes, it makes a copy of the char[] everytime.

It's important to note that this is one implementation of toString, and another implementation may obviously be different.

Upvotes: 5

Related Questions