80

在以下代码上:

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)

为什么?

4

6 回答 6

99

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

Collections.copyJavaDocs的关键部分:

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

You should just pass the List to the ArrayList's constructor to copy all of the List to avoid the issue altogether.

于 2011-05-27T03:52:05.577 回答
30

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

ArrayList <Integer> numbersCopy = new ArrayList<Integer>(numbers);
于 2011-05-27T03:51:18.357 回答
6

The constructor ArrayList(Collection<? extends E> c) will copy every elements from c into the newly created instance, thus copying numbers into numbersCopy. It is the same as numbersCopy.addAll(numbers) also, which is really what you need.

It does make sense that Collection.copy requires the dest array to be large enough to hold all elements from the source array. A similar analogy is the C function memcpy and the like.

于 2011-05-27T04:03:07.837 回答
1

While creating an ArrayList to copy another ArrayList using Collections.copy() method, we need to make sure that the destination List contains same number of values (not just same size) as source List. For example, if source ArrayList has values [Red,Blue,Green], then the destination ArrayList should also contain same number of elements like [Orange,Yellow,Blue].If we create an ArrayList with same size that of source ArrayList, it will give OutOfBounds exception.

于 2019-03-11T14:14:48.390 回答
1

You can also use, Collections.addAll like Assume we need to copy List1 to List2, then List2.addAll(List1); Here the files will be added, if you want it more efficient then make sure you clear the list2 before adding the items of list1, like this, list2.clear();

于 2020-08-25T03:30:47.970 回答
-1

In java 8 +

List<Integer> numbersCopy = numbers.stream().collect(Collectors.toList());

It easier in java 10+

List<Integer> numbersCopy = List.copyOf(numbers);

List.copyOf() returns an unmodifiable List containing the elements of the given Collection.

于 2019-10-20T15:34:32.687 回答