为什么AbstractCollection.toArray()处理更改大小的情况?

时间:2013-10-18 10:45:11

标签: java arrays collections concurrency

AbstractCollection中有这个奇怪的代码:

public Object[] toArray() {
    // Estimate size of array; be prepared to see more or fewer elements
    Object[] r = new Object[size()];
    Iterator<E> it = iterator();
    for (int i = 0; i < r.length; i++) {
        if (! it.hasNext()) // fewer elements than expected
            return Arrays.copyOf(r, i);
        r[i] = it.next();
    }
    return it.hasNext() ? finishToArray(r, it) : r;
}

部分&#34;准备好看更多或更少的元素&#34;恕我直言是一种纯粹的无意义:

  • 如果集合在此期间发生变化,迭代器无论如何都会抛出ConcurrentModification例外。
  • 我还没有发现任何非并发子类支持这一点,尤其是
    • ArrayList使用Arrays.copyOf(elementData, size),这可能(由于可见性问题)在调整大小时复制了一堆null而不是数据,
    • 如果您足够幸运,
    • LinkedList会引发ArrayIndexOutOfBoundsException

我忽略了什么吗?

您是否支持收藏中的此功能(适用于一般用途)?

1 个答案:

答案 0 :(得分:2)

来自toArray()的JAVA DOC

  

此实现返回包含所有元素的数组   由此集合的迭代器以相同的顺序返回,存储在   数组的连续元素,从索引0开始。长度   返回数组的数量等于返回的元素数   迭代器,即使此集合的大小发生变化   迭代,如果集合允许并发可能会发生   迭代期间的修改。只调用size方法   优化提示;即使迭代器返回正确的结果   返回不同数量的元素