对于addAll操作,是否存在复杂度为O(1)而不是O(n)的Java集合,还是我必须实现自己的集合?使用高效的链表,Collection1.addAll(Collection2)操作应该将第二个集合附加到第一个集合,将集合2的第一个节点添加到集合1的最后一个节点,其他集合遵循。但是我并没有读到它似乎使用迭代器的文档,所以我猜复杂性是O(collection2.size)。
是吗?
答案 0 :(得分:3)
即使对链接列表进行优化也只有在将项目从一个链接列表移动到另一个链接列表时才能生效。
然而,你可以建立一种自己的集合,它有一个更多层次的间接,i。即其中包含一系列集合。这样,添加整个集合非常便宜,迭代也是如此。然而,索引或长度确定可能变得非常昂贵。
答案 1 :(得分:3)
ArrayList可能与它在这方面的表现一样好,但它实际上也取决于提供的集合。最佳情况复杂度为O(1),但前提是所提供的Collection的T
方法也具有恒定的复杂性。
执行实际分配的System.arrayCopy()调用是O(1),无论如何很复杂,见下文:
toArray()
对于// java.util.ArrayList.addAll
// Oracle JDK 1.8.0_91
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray(); // O(?) <-- depending on other type
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
是否为恒定时间操作存在一些分歧。 Some say no。 Others suggest it is。
根据to this benchmark I hacked together,它位于中间位置。复制时间在大约100个数组项目中保持不变,但从那里开始线性增长,我猜测那里涉及某种分页。如此有效,除非数组非常小,否则System.arrayCopy
具有线性时间复杂度。