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;
}
Run Code Online (Sandbox Code Playgroud)
这是AbstractCollection.toArray方法的实现代码.
if (! it.hasNext()) // fewer elements than expected
return Arrays.copyOf(r, i);
Run Code Online (Sandbox Code Playgroud)
我不明白上面代码的用法.我怀疑代码用于避免在调用方法时更改大小.所以我有两个问题:
好吧,方法的javadoc就是这样:
/**
* {@inheritDoc}
*
* <p>This implementation returns an array containing all the elements
* returned by this collection's iterator, in the same order, stored in
* consecutive elements of the array, starting with index {@code 0}.
* The length of the returned array is equal to the number of elements
* returned by the iterator, even if the size of this collection changes
* during iteration, as might happen if the collection permits
* concurrent modification during iteration. The {@code size} method is
* called only as an optimization hint; the correct result is returned
* even if the iterator returns a different number of elements.
*
* <p>This method is equivalent to:
*
* <pre> {@code
* List<E> list = new ArrayList<E>(size());
* for (E e : this)
* list.add(e);
* return list.toArray();
* }</pre>
*/
Run Code Online (Sandbox Code Playgroud)
我发现这里有两件有趣的事情要提到:
是的,你是对的,就像javadoc sais一样,这个方法准备好正确地返回,即使集合在同一时间被修改了.这就是为什么初始尺寸只是一个提示.迭代器的使用还确保避免"并发修改"异常.
很容易想象一个多线程情况,其中一个线程在Collection中添加/删除元素,而另一个线程在其上调用"toArray"方法.在这种情况下,如果Collection不是线程安全的(例如通过Collections.synchronizedCollection(...)方法获得,或者通过手动创建同步访问代码),您将进入同时修改和编译的情况.