java.lang.IndexOutOfBoundsException:Source不适合dest

and*_*and 65 java collections arraylist indexoutofboundsexception

在以下代码中:

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

我收到错误:

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)
Run Code Online (Sandbox Code Playgroud)

为什么?

pic*_*ypg 80

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

Collections.copyJavaDocs的关键部分:

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

你应该只是传递ListArrayList构造函数来复制所有的东西List以完全避免这个问题.

  • 我低估了这一点,因为将它添加到构造函数中会执行[b]浅[/ b]副本,并且不会与深层副本相同.操作原始列表中的元素,也会在"复制到"列表中操作它们 (7认同)
  • @Boy你的观点不正确.参见[ArrayList的源代码](http://hg.openjdk.java.net/jdk7/modules/jdk/file/a37326fa7f95/src/share/classes/java/util/ArrayList.java#l150) copy_of list_是通过调用`toArray`和[`Arrays.copyOf`](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#copyOf( U [],%20int,%20java.lang.Class)).在`numbersCopy = new ArrayList <Integer>(数字)`之后对任一列表所做的更改确实_not_影响另一个.这肯定会破坏构造函数的目的(并且它需要一个`Collection`而不是一个`List`). (5认同)
  • @Boy 除非您了解到 _elements 本身_ 没有为真正的深拷贝而重建?由于 Java 不需要复制构造函数,因此这几乎是不可能的要求,并且 [`Collections.copy` 也不会执行](http://hg.openjdk.java.net/jdk7/modules/jdk/file/ a37326fa7f95/src/share/classes/java/util/Collections.java#l545)。 (2认同)
  • 我不知道“新”并不会影响彼此的名单。抱歉,不正确... (2认同)

pax*_*blo 20

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

ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);
Run Code Online (Sandbox Code Playgroud)

  • 它复制参考 (8认同)

Yan*_*hon 6

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

Collection.copy要求dest数组足够大以容纳source数组中的所有元素确实是有道理的。类似的类比是 C 函数memcpy等。