Collections.copy是否已损坏(在OpenJDK 6中)?

时间:2009-11-11 16:26:52

标签: java

有时我似乎效率很低。当我差不多完成输入时,我设法在Sun找到了相应的错误报告。然后我想好了,不妨发布它,有截图和所有。答案如下。

我知道,“SELECT没有被打破”,这总是我的错。但在这里,我真的不明白为什么它应该是。我的代码片段:

List<IGraphEdge> rgSrc = this._rgGetPath();
List<IGraphEdge> rgDst = new ArrayList<IGraphEdge>(rgSrc.size());
Collections.copy(rgDst, rgSrc);

这会抛出IndexOutOfBoundException消息

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

在调试器中,当我进入Collections.copy时,两个ArrayList实例看起来像这样:

Debugger view http://static.theuprightape.net/ql/img/debugger.png

因此,dest中有一个容量来容纳src中的一个元素,但是,size的{​​{1}}自然仍为0,毕竟这个是我想通过调用dest来改变的。

查看OpenJDK实现的源代码,很清楚为什么会抛出错误:

copy()

所以请告诉我,这是一个错误,或者我做错了什么?

4 个答案:

答案 0 :(得分:4)

它没有查看容量,它正在查看大小。也就是说,目标应包含要由源列表覆盖的元素。

我从未遇到过这样有用的案例。通常你想要的是List实现之一或addAll接口的Collection方法中的复制构造函数。

答案 1 :(得分:2)

我不是第一个碰到这个,但它总是你的错。根据Sun对this bug report的回复,Collections.copy不打算像这样使用,您应该使用List.appendAll()代替。

所以我修改了我的代码看起来像这样,它起作用了:

List<IGraphEdge> rgSrc = this._rgGetPath();
List<IGraphEdge> rgDst = new ArrayList<IGraphEdge>(rgSrc.size());
rgDst.addAll(rgSrc);

咄。

答案 2 :(得分:2)

来自Collection.copy的文档:

  

从一个元素复制所有元素   列入另一个。之后   操作,每个复制的索引   目的地列表中的元素将   与其中的索引相同   来源清单。 目的地列表必须   至少与来源一样长   列表。如果它更长,剩下的   目的地列表中的元素是   不受影响。

我同意你的看法,这并不是非常直观,但你真正想做的事情似乎更像是克隆()。

答案 3 :(得分:1)

Javadocs说:

  

抛出:IndexOutOfBoundsException - 如果   目的地列表太小了   包含整个源列表。

所以它似乎符合规范。