【问题标题】:Java Collection addAll complexityJava 集合添加所有复杂性
【发布时间】:2016-11-14 10:05:15
【问题描述】:

对于 addAll 操作,是否存在复杂度为 O(1) 而不是 O(n) 的 Java 集合,还是我必须实现自己的集合?使用有效的链表,Collection1.addAll(Collection2) 操作应该将第二个集合附加到第一个集合,将 collection2 的第一个节点添加到集合 1 的最后一个节点,然后其他集合。但并不是我读到的文档似乎使用了一个迭代器,所以我猜复杂度是 O(collection2.size)。

对吗?

【问题讨论】:

标签: java collections linked-list asymptotic-complexity


【解决方案1】:

ArrayList 在这方面可能和它一样好,但它实际上也取决于提供的集合。最佳情况复杂度为 O(1),但前提是提供的 Collection 的 toArray() 方法也具有恒定复杂度。

进行实际分配的System.arrayCopy()调用是O(1),反正很复杂,见下文:

// 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;
}

对于System.arrayCopy 是否为常数时间运算存在一些分歧。 Some say noOthers suggest it is

根据to this benchmark I hacked together,它位于中间某处。复制时间几乎保持不变,最多大约 100 个数组项,但从那里开始线性增长,我猜那里涉及某种分页。如此有效,System.arrayCopy 具有线性时间复杂度,除非数组非常小。

【讨论】:

  • 谢谢你,在我的情况下,集合是一个链表(一个链表我不知道用英语怎么说)所以我猜 toArray 操作是 O(n)。跨度>
  • 你确定吗? stackoverflow.com/questions/7165594/… 声称有所不同。此外,我很确定ensureCapacityInternal 也在O(N) 中。
  • 第一部分是宗教战争的根源,没错。我认为从 Java 的角度来看,这是一个原子操作。这里存在分歧,但这个答案支持我的理论:stackoverflow.com/a/2772176/342852
  • 第二部分错了。 ensureCapacityInternal 的最佳情况复杂度为 O(1),最坏情况复杂度为 O(n),但最佳情况与最差情况的比率足以使线性方面可以忽略不计。
  • System.arrayCopy 没有参数是 O(1)。它必须遍历数组中的每个项目来复制它。仅使用 memmove 并不会神奇地使其成为 O(1),因为 memmove 不是 O(1),尽管它是 Java 中的一条指令。如果从 Java 调用任何 C 函数确实是 O(1),那么您也可以说任何 NP 问题实际上都是 O(1):只需编写一个解决问题的 C 函数并从 Java 调用它!跨度>
【解决方案2】:

只有将项目从一个链表移动到另一个链表时,才能对链表进行优化。

但是,您可以构建一种自己的集合,它具有更多的间接级别,即。 e.其中包含集合的集合。这样,添加整个集合非常便宜,迭代也是如此。但是,索引或长度确定可能会变得非常昂贵。

【讨论】:

  • 谢谢,当然这取决于具体情况。对于长度确定,我认为只需简单地将两种尺寸相加即可。
  • @Kaizokun 如果只有两个。如果您以最大的灵活性设计此类,也许会更多。
  • 当然,每次我附加一个集合时,我都会把大小加起来:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 2014-04-17
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多