java.lang.IndexOutOfBoundsException:Source不适合dest

问题描述 投票:63回答:4

在以下代码中:

static void findSubsets (ArrayList<Integer> numbers, int amount, int index)
{
    ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers.size());
    Collections.copy(numbersCopy, numbers);
}

我收到错误:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest
        at java.util.Collections.copy(Collections.java:548)
        at backtracking2.Main.findSubsets(Main.java:61)

为什么?

java arraylist collections indexoutofboundsexception
4个回答
78
投票

容量不等于大小。您传入的size参数只是为该大小分配了足够的内存。它实际上并没有定义元素。这实际上是对Collections.copy的愚蠢要求,但它仍然是一个。

来自Collections.copy JavaDocs的关键部分:

目标列表必须至少与源列表一样长。如果它更长,则目标列表中的其余元素不受影响。

你应该将List传递给ArrayList的构造函数来复制所有的List以完全避免这个问题。


18
投票

这是一个非常好的问题,它几乎肯定与设置集合容量不一定分配底层对象这一事实有关,但是为什么你这样做当你可以:

ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);

4
投票

构造函数ArrayList(Collection<? extends E> c)会将c中的每个元素复制到新创建的实例中,从而将numbers复制到numbersCopy中。它也和numbersCopy.addAll(numbers)一样,这正是你所需要的。

有意义的是,Collection.copy要求dest数组足够大以容纳来自source数组的所有元素。类似的类比是C函数memcpy等。


1
投票

在创建ArrayList以使用ArrayList方法复制另一个Collections.copy()时,我们需要确保目标List包含与源List相同数量的值(不仅仅是相同大小)。例如,如果源ArrayList具有值[红色,蓝色,绿色],那么目标ArrayList也应该包含相同数量的元素,如[橙色,黄色,蓝色]。如果我们创建一个与源ArrayList大小相同的ArrayList,它会给OutOfBounds例外。

© www.soinside.com 2019 - 2024. All rights reserved.