Java ArrayList IndexOutOfBoundsException尽管给出了初始容量

Ven*_*tta 25 java arrays arraylist

当我做

ArrayList<Integer> arr = new ArrayList<Integer>(10);
arr.set(0, 1);
Run Code Online (Sandbox Code Playgroud)

Java给了我

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.set(Unknown Source)
    at HelloWorld.main(HelloWorld.java:13)
Run Code Online (Sandbox Code Playgroud)

有没有一种简单的方法可以预先保留ArrayList的大小,然后立即使用索引,就像数组一样?

jh3*_*314 24

这个怎么样:

ArrayList<Integer> arr = new ArrayList<Integer>(Collections.nCopies(10, 0));
Run Code Online (Sandbox Code Playgroud)

这将使用10个零来初始化arr.然后您可以立即使用索引.


Ste*_* P. 14

以下是来源ArrayList:

构造函数:

public ArrayList(int initialCapacity) 
{
     super();

     if (initialCapacity < 0)
          throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
     this.elementData = new Object[initialCapacity];
}
Run Code Online (Sandbox Code Playgroud)

你打电话给set(int, E):

public E set(int index, E element) 
{
     rangeCheck(index);  
     E oldValue = elementData(index);
     elementData[index] = element;
     return oldValue;
}
Run Code Online (Sandbox Code Playgroud)

Set来电rangeCheck(int):

private void rangeCheck(int index) 
{
    if (index >= size) {
         throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
}
Run Code Online (Sandbox Code Playgroud)

它可能很微妙,但是当你调用构造函数时,尽管初始化了一个Object[],但你没有初始化size.因此,从rangeCheck,你得到的IndexOutOfBoundsException,因为size是0. set(int, E)你可以使用add(E e)(在列表的末尾添加e类型E,在你的情况下:),而不是使用,add(1)这将不会发生.或者,如果它适合您,您可以按照另一个答案中的建议将所有元素初始化为0.

  • 如果您认为ArrayList实现List接口,则更有意义.List没有类似于"Initial Capacity"的概念.通过向其添加值来增加列表. (4认同)
  • @CodeNoob没问题.我同意*容量*一词具有误导性,但我认为以这种方式实际上是有意义的.`size`跟踪数组中实际有多少元素,因此初始化后'size`为0是正确的,关于`set/add`,Bakuriu说:*"这是常见的设计(在python中也是一样):set方法不会增加序列/集合的大小.如果你想增加大小,那么你想要添加一些东西."* (3认同)