ArrayList<Integer>arr1=new ArrayList<Integer>();
arr1.add(1);
arr1.add(2);
arr1.add(3);
ArrayList<Integer>copyArray=new ArrayList<Integer>(arr1);
上面的代码将一个arrayList复制到另一个arrayList是在O(1)中工作还是深入到它的O(n),似乎要将一个数组的每个元素复制到另一个数组,它会迭代一个一个会导致O(n),还是只是对象池的引用?
答案 0 :(得分:3)
期待来源:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
ArrayList(Collection)
构造函数调用toArray()
调用Arrays.copyOf
:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
这里的重要部分是System.arraycopy
,这是本地电话。 Another question on SO解决了这个调用的时间复杂性,结论似乎是在最坏的情况下这个调用是O(n)但是有些系统可能会使用块副本来处理某些数据类型(比如我想象的基元),从而导致运行时比循环迭代更有效。
答案 1 :(得分:1)
在内部,它使用Arrays.copyOf,它进一步使用复杂度为O(n)的System.arraycopy。查看以下来源:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
答案 2 :(得分:1)
检查源代码,ArrayList(Collection<? extends E> c)
构造函数在内部调用c.to Array()
Java Doc for toArray()https://docs.oracle.com/javase/9/docs/api/java/util/ArrayList.html#toArray--
表示它执行源数组的深层复制并返回安全复制的数组。因此,客户端对重新调整的数组所做的任何更改都不会影响ArrayList的内部数据结构。所以在最坏的情况下是O(n)。