【问题标题】:Unexpected IndexOutOfBoundException when getting value of an ArrayList [duplicate]获取 ArrayList 的值时出现意外的 IndexOutOfBoundException [重复]
【发布时间】:2016-09-15 22:22:55
【问题描述】:
public static void main(String[] args) {
List<Integer> values = new ArrayList<>(30);
for (int i = 0; i < values.size(); i++){
values.add(i, 0);
}
int j = 0;
int ghh = values.get(j);
}
上面是一个简单的代码sn-p,它在最后一行给出OutOfBoundException。为什么会抛出这个异常?我真的需要使用 for 循环来初始化列表中所有元素的 0 值吗?
【问题讨论】:
标签:
java
arraylist
indexoutofboundsexception
【解决方案1】:
你的 for 循环什么都不做,因为 values.size() 是 0。这就是values.get(j) 抛出异常的原因(列表仍然为空)。
将循环改为
for (int i = 0; i < 30; i++){
values.add(i, 0);
}
当您使用此构造函数创建 ArrayList 实例时 - new ArrayList<>(30) - 您指定的是初始容量,而不是初始大小。初始大小为0。
【解决方案2】:
数组列表构造函数 'ArrayList(int initialCapacity)' 创建一个接收初始容量的空列表。
List<Integer> values = new ArrayList<>(30);
values 此时是一个空列表。您设置了初始容量,但这不会在列表中创建任何元素。
for (int i = 0 ;i<values.size() ; i++){
values.size() 为 0,因此循环内的行没有被执行。
int ghh = values.get(j);
values 仍然是一个空列表,因此 values.get(0) 会抛出一个 IndexOutOfBoundException
我真的需要使用 for 循环来初始化列表中所有元素的 0 值吗?
您需要使用 for 循环手动将元素添加到列表中。
作为替代方案,在 Java8 中,您可以使用 Stream 来生成列表:
List<Integer> list = Stream.generate(()-> 0).limit(30).collect(Collectors.toList());
【解决方案3】:
您的问题是您假设 new ArrayList<>(30) 创建了一个已“分配”了 30 个插槽的列表(因此 .size() 将返回 30)。
但实际情况并非如此。此构造函数仅指定列表的初始 容量。这意味着,您现在可以添加 30 个元素,并且底层列表不需要动态增长。但是您仍然必须添加至少一个元素,然后才能执行get(0)。