Java 为什么';t Collections.copy是否增加目标的大小?

Java 为什么';t Collections.copy是否增加目标的大小?,java,list,collections,Java,List,Collections,我正在使用以下代码: List<Object> dest = new LinkedList<Object>(); Collections.copy(oldList, src); 我知道如何解决这个问题,但我不明白的是: 当我手动添加元素时,列表会自动增加容量。为什么Collections#copy不能做到这一点?,因为这就是它的实现方式。如果你看到这个的源代码,你会看到 if (srcSize > dest.size()) throw new Index

我正在使用以下代码:

List<Object> dest = new LinkedList<Object>();
Collections.copy(oldList, src);
我知道如何解决这个问题,但我不明白的是:


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

,因为这就是它的实现方式。如果你看到这个的源代码,你会看到

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

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

正如StinePike在中所说:这就是它的实现方式。这只是一种方便的方法,您可以使用它来代替类似for循环的方法

for (int i=0; i<src.size(); i++)
{
    dst.set(i, src.get(i));
}
是一种实用方法,适用于任何
列表
。此方法旨在重新使用现有阵列,而不是分配任何内存。因此,这可能是有效的,否则您可能会使用
ArrayList(Collection)
构造函数,它将为您完成扩展工作。大小约束和扩展仅与
ArrayList
相关,这也是不将此行为添加到方法的原因之一。这只是为了一个特定的
列表
实现而需要额外的代码。这不是接口编程的工作方式


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

如果您看到了
方法的实现,在复制操作后,它会在目的地列表中维护相同的索引

要在索引处设置元素,应使用
set(int)
方法
set(int)
方法期望索引出现在目标列表中(与
add(Object)
不同,后者在没有容量时扩展列表)

想象一下,如果此方法在复制时使用了
add(Object)
,并且
dest
列表已经有了一些元素,那么新的元素(来自
src
)就会添加到
dest
列表的末尾,破坏复制契约(这意味着相同的元素@各自相同的指数


因此,如果目标列表没有您假定的源列表长,那么该方法将引发异常,
列表的大小是可变的,并且
集合.copy()
并不认为理论上将此类的用途扩展到实现
列表的所有类,而不仅仅是可变类。

Javadoc解释了该行为。请阅读Javadoc:


但他们为什么这样做?这不是一个令人满意的答案。我看不出有什么好处。这是一个正确的答案。该方法称为copy,它执行文档中指定的操作:它复制元素。没有指向目标修改的引用。不,这个答案严格来说是不正确的。行为是这是因为该方法在API文档中是这样定义的。这不是因为一些供应商决定在JVM的任意实现中放入几行代码。如果您阅读我答案的第一行..因为它是如何实现的…我粘贴此实现只是为了显示一个实现…感谢downvoting无论如何(y)@斯汀派克:我读了你答案的第一行,这正是我批评的那一行。Phillip看到的行为在API文档中有定义。正如我所说,查看API的任意实现并推断该方法所做或应该做的任何假设都是一个坏主意。
列表
接口s扩展列表的方法
add
addAll
。@jarnbjo rohit的意思是扩展大小的方法,但保留内容unaffected@jarnbjo嗯,我不是那个意思。但是我仍然更新了答案。问题是这个问题没有正确的答案。@PhillipSander:这可能是他的意思,但为什么要呢d在这种情况下是否相关?如果复制方法将扩展目标列表以适应整个源列表,它可以通过使用
add
方法添加额外的元素来完成,而不是用
set
替换它们@jarnbjo用一些合理的答案更新了答案。可能会看一看。关于超过固定大小集合的容量可以由该集合处理。此实用方法不需要强制执行它。事实是,它确实执行了,但OP正在询问原因-此答案没有提供他所寻求的推理。您正在反转问题,实用方法不强制执行任何有关可变性的内容,而是er表示,要复制到的集合至少与源集合一样大-如果实用程序方法要求集合是可变的,它将强制执行某些内容。您提出了可变性作为原因,而不是我。:)不,OP假设实现列表的所有类的集合大小都会被该方法视为可变的。如果这不成立,
add
将失败,然后,当导致需要增加大小的操作发生时,目标列表可能会抛出该异常-不需要通过实用程序方法强制执行该异常。考虑到source大于dest,它当然可能以使用
set(index)的方式实现该异常
替换现有元素,并
添加
添加更多元素。您是正确的,但概念上它与任何其他副本相同。考虑将文件从一个驱动器复制到另一个驱动器。操作系统不会扩展目标驱动器以容纳源文件,而是会抱怨。。也许我们可以这样想:)
for (int i=0; i<src.size(); i++)
{
    dst.set(i, src.get(i));
}
dest.addAll(src);