为什么Collections.copy没有增加目标的大小?

时间:2014-02-24 11:43:20

标签: java list collections

我正在使用以下代码:

List<Object> dest = new LinkedList<Object>();
Collections.copy(oldList, src);

当我执行代码时,我得到一个例外:

java.lang.IndexOutOfBoundsException: Source does not fit in dest
    at java.util.Collections.copy(Collections.java:589)

我知道如何解决这个问题,但我不明白的是:

当我手动添加元素时,列表会自动增加容量。为什么Collections#copy不能这样做?

6 个答案:

答案 0 :(得分:4)

正如StinePike已在https://stackoverflow.com/a/21986805中所说:这就是它的实施方式。它只是一种方便的方法,你可以使用而不是像

这样的for循环
for (int i=0; i<src.size(); i++)
{
    dst.set(i, src.get(i));
}

关于自动尺寸增加的问题:听起来好像你实际上正在寻找类似Collection#addAll(Collection)的东西 - 所以在这种情况下

dest.addAll(src);

答案 1 :(得分:3)

因为这是它的实现方式。如果您看到此method的源代码,您会看到

 if (srcSize > dest.size())
    throw new IndexOutOfBoundsException("Source does not fit in dest");

因此,如果您想实现自动增量,那么请编写自己的方法。

答案 2 :(得分:3)

Collections#copy()是一种实用工具方法,适用于任何List。此方法旨在重新使用现有阵列,而不是分配任何内存。所以,这可能是有效的,否则你可能会使用ArrayList(Collection)构造函数,它将为你做扩展工作。大小约束和扩展仅与ArrayList相关的事实也可能是一个原因,而不是将此行为添加到方法中。仅仅为了特定的List实现,这只是额外的代码。这不是编程接口的工作方式。

由于文档中有明确提及,他们希望您遵循它。

答案 3 :(得分:1)

如果您看到Collection.copy方法的实施,它会在来源目标<中维护 相同的索引 / strong>列表,复制操作后。

要在索引处设置元素,应使用set(int)方法。 set(int)方法期望索引存在于目标列表中(与add(Object)不同,如果没有容量,则扩展列表)。

想象一下,如果此方法在复制时使用add(Object)并且dest列表已经有了一些元素,那么新元素(来自src)将在最后添加dest列表, 打破 复制合同(这意味着相同元素@相同的索引)< / p>

因此,如果目标列表不像源列表那样长,则该方法抛出异常

答案 4 :(得分:0)

答案 5 :(得分:-1)

您认为List大小是可变的,而Collections.copy()并不认为这理论上将此类的目的扩展到实现List接口的所有类而不是仅仅可变的类