(Давайте построим на платформе SE 6)
Все зависит от фактической реализации коллекции. В вашем примере мы имеем
Collection<Integer> col = new ArrayList<Integer>();
и addAll
метод в ArrayList
переопределяется. Никаких итераций.
Вот источник:
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
Как вы могли заметить, c.toArray()
также зависит от фактической реализации. Опять же, в вашем случае Arrays.asList()
приводит к ArrayList
, чья версия метода toArray()
выглядит следующим образом:
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
Этот статический метод основан на System.arraycopy
На самом деле мы имеем дело с двумя вызовами System.arraycopy
, что на самом деле не так уж и плохо, потому что это нативный метод, специально оптимизированный для текущей операционной системы.
Итак, подведем итоги в стиле мистера Полигенубрикантс:
- varags + autoboxing создает
Integer[]
Arrays.asList
создает ArrayList<Integer>
ArrayList.addAll
звонки System.arraycopy(size)
x2, размер = 5
В вашем случае 5 объектов в массиве Collections.addAll
, конечно, быстрее. НО не имеет значения при таком маленьком размере массива. С другой стороны, если это было, скажем, 100k элементов в массиве, то col.addAll(Arrays.asList(...))
гораздо более эффективно, потому что с нативным методом это единственный memcpy / memmove, с которым мы имеем дело, а не 100k итераций / операций копирования.
И снова, все зависит от реализации коллекции. LinkedList
например будет перебирать его, как и ожидалось.