5

我得到了StringIndexOutOfBoundsException一个setCharAt(int index, char ch)

StringBuilder word = new StringBuilder(4);

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

StringBuilder(int capacity)构造一个字符串构建器,其中没有字符,初始容量由容量参数指定。

setCharAt(int index, char ch):指定索引处的字符设置为 ch。

我唯一能想到的是没有分配内存,但那有什么意义StringBuilder(int capacity)呢?

4

3 回答 3

6

只需使用StringBuilder.append()

您使用的构造函数不会将数据放入 StringBuilder。

它仅指定了 StringBuilder 的实际大小(我认为这是为了提高性能)。

在您真正将内容放入 StringBuilder 之前,您的代码将抛出异常。

请注意,您引用的文档明确说明了这一点:

"构造一个没有字符的字符串生成器 ... "

于 2013-06-08T00:53:22.453 回答
5

我唯一能想到的是没有分配内存,但是StringBuilder(int容量)有什么意义呢?

关键是提供一个预先机会来分配足够大的内存块来处理将要插入的所有数据。当超出容量时,必须在内部分配新的内存块,并复制旧内存中的所有值。正如您可以想象的那样,如果它发生多次,这可能会成为性能负担。

这种行为并不奇怪或出乎意料,实际上它与封装的做法非常一致。

ArrayList做什么?AnArrayList由数组支持,并且使用足够的初始容量性能更高,但是这样做仍然不允许任意访问数组的索引。

我认为奇怪的行为是将 aStringBuilder视为 a 的表示char[]。表示已正确封装,不要以奇怪的方式戳它。

于 2013-06-08T01:02:57.347 回答
4

这似乎有点奇怪的行为StringBuilder

AbstractStringBuilder(它继承的)中,构造函数定义为:

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

但是,当使用 时setCharAt(),我们count改为检查:

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

因此,由于我们没有count使用初始构造函数进行设置,因此我们面临着一个错误。

countappend()replace()insert()和中重新定义setLength()。你也可以通过调用来解决你的问题setLength(4);但是,正如@jahroy 指出的那样,使用它更简单append()

相关源代码:StringBuilder,AbstractStringBuilder

于 2013-06-08T00:57:20.720 回答