Steve P.
Steve P.

Reputation: 14699

Simple StringBuilder constructor/method issue

I got a StringIndexOutOfBoundsException for setCharAt(int index, char ch):

StringBuilder word = new StringBuilder(4);

for(int i = 0; i < 4; i++)
    word.setCharAt(i,'-');

StringBuilder(int capacity): Constructs a string builder with no characters in it and an initial capacity specified by the capacity argument.

setCharAt(int index, char ch): The character at the specified index is set to ch.

The only thing I can think of is that no memory was allocated, but then what's the point of StringBuilder(int capacity)?

Upvotes: 5

Views: 608

Answers (3)

Tim Bender
Tim Bender

Reputation: 20442

The only thing I can think of is that no memory was allocated, but then what's the point of StringBuilder(int capacity)?

The point is to provide an up front opportunity to allocate a sufficiently large chunk of memory to handle all the data that will be inserted. When the capacity is exceeded, internally a new chunk of memory will have to be allocated and all the values from the old memory copied over. As you can imagine, this could be a performance burden if it occurs a multitude of times.

The behavior is not really odd or unexpected, in fact it is quite consistent with the practice of encapsulation.

What would ArrayList do? An ArrayList is backed by an array, and using a sufficient initial capacity is more performant, however doing so still does not allow arbitrary access to indices of the array.

I think the odd behavior is thinking of a StringBuilder as a representation of a char[]. The representation is properly encapsulated at it is, don't poke at it in curious ways.

Upvotes: 5

jahroy
jahroy

Reputation: 22692

Just use StringBuilder.append()

The constructor you're using does nothing to put data in the StringBuilder.

It only specifies a practical size for the StringBuilder (which I believe is for performance).

Until you actually put stuff in the StringBuilder, your code will throw Exceptions.

Note that the documentation you've quoted says this explicitly:

"Constructs a string builder with NO CHARACTERS in it..."

Upvotes: 6

Cat
Cat

Reputation: 67502

This seems like a bit of an odd behavior in StringBuilder.

In AbstractStringBuilder (which it inherits), the constructor is defined as:

AbstractStringBuilder(int capacity) {
    value = new char[capacity];
}

However, when using setCharAt(), we check count instead:

public void setCharAt(int index, char ch) {
    if ((index < 0) || (index >= count))
        throw new StringIndexOutOfBoundsException(index);
    value[index] = ch;
}

So, since we didn't set count by using the initial constructor, we have an error thrown in our faces.

count is redefined in append(), replace(), insert(), and setLength(). You could solve your problem by also calling setLength(4); however, as @jahroy pointed out, it is simpler to just use append().

Relevant source codes: StringBuilder, AbstractStringBuilder

Upvotes: 4

Related Questions