ArrayList.clear() 和 ArrayList.removeAll() 有啥区别?

Posted

技术标签:

【中文标题】ArrayList.clear() 和 ArrayList.removeAll() 有啥区别?【英文标题】:What is the difference between ArrayList.clear() and ArrayList.removeAll()?ArrayList.clear() 和 ArrayList.removeAll() 有什么区别? 【发布时间】:2011-10-25 07:32:45 【问题描述】:

假设arraylist定义为ArrayList<String> arraylist,那么arraylist.removeAll(arraylist)是否等同于arraylist.clear()

如果是这样,我可以假设clear() 方法对于清空数组列表更有效吗?

使用arraylist.removeAll(arraylist) 代替arraylist.clear() 有什么注意事项吗?

【问题讨论】:

这个问题的一个可能推论:什么时候可以用一个代替另一个? @Corey:每个人什么时候都想使用arraylist.removeAll(arraylist)?我认为绝对没有理由这样做。 @Joachim Sauer 这正是我想要验证的。谢谢+2。但是elementData[i] = nulle.remove() 之间的区别重要吗? 没有理智的理由使用arrList.removeAll(arrList) 而不是arrList.clear()arrList1.removeAll(arrList2) 是另一回事。 如果 removeAll() 的实现只从这一行开始,那么整个讨论会更有趣! if (c == this && !isEmpty()) clear(); return true; 。我必须将此作为补丁提交给 OpenJDK! ;-) 【参考方案1】:

Clear 更快,因为它不会遍历要删除的元素。该方法可以假设所有元素都可以删除。

Remove all 并不一定意味着删除列表中的所有元素,只有那些作为参数提供的元素应该被删除。因此,需要更多的努力来保留那些不应该删除的内容。

澄清

“循环”是指它不必检查是否应该保留元素。它可以设置对null 的引用,而无需搜索提供的要删除的元素列表。

Cleardeleteall 快​​。

【讨论】:

我很确定ArrayList.clear() 也必须循环播放。 @JVerstry 你的意思是 clear() 不会删除它从 ArrayList 中删除的元素吗? 错误,clear 会循环内部数组并将所有引用设置为 null,以便让垃圾收集器完成其工作。 @Joachim, @devconsole:我认为他的意思是它不必循环/迭代作为参数给出的列表。 target.removeAll(param) 将迭代 param 然后调用 target.contains(...) 迭代 target -3 有点苛刻。如果 JVerstry 愿意,他可以从头开始编写自己的不循环的 Java 实现。 clear() 可以在 O(1) 中实现,没有循环,而 removeAll() 必须有某种 O(n) 算法,没有办法满足 removeAll() API 的在不检查所有元素的情况下签订合同。【参考方案2】:

它们有不同的用途。 clear() 清除该类的一个实例,removeAll() 删除所有给定对象并返回操作状态。

【讨论】:

您能否提供一个资源来阅读上述问题以供进一步参考 @KasunSiyambalapitiya accepted answer 怎么样,其中包含两者的源代码?【参考方案3】:

除非有特定的优化来检查传递给removeAll() 的参数是否是集合本身(我高度怀疑是否存在这样的优化)它将是显着 比简单的 .clear() 慢。

除此之外(至少同样重要):arraylist.removeAll(arraylist) 只是迟钝、令人困惑的代码。这是“清除此集合”的一种非常倒退的说法。与非常容易理解 arraylist.clear() 相比,它有什么优势?

【讨论】:

【参考方案4】:

clear()的源代码:

public void clear() 
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;

removeAll()的源代码(定义在AbstractCollection):

public boolean removeAll(Collection<?> c) 
    boolean modified = false;
    Iterator<?> e = iterator();
    while (e.hasNext()) 
        if (c.contains(e.next())) 
            e.remove();
            modified = true;
        
    
    return modified;

clear() 更快,因为它不必处理所有这些额外的方法调用。

正如 Atrey 指出的那样,c.contains(..)removeAll 的时间复杂度增加到 O(n2),而不是 clear 的 O(n)。

【讨论】:

注意c.contains(...) 平方运算的时间复杂度将使这个答案完整。 源强在这一个。 (对于所有其他答案:使用源,Luke。)注意 clear() 可以如何实现为一行,size=0;但是垃圾收集不知道要收集数组中无法访问的部分中的元素。 e.remove() 要复杂得多! e.remove() 也使复杂性平方,就像 c.contains(...) 一样。在 ArrayList 上,e.remove() 调用 ArrayList.remove(int index),它必须将数组的其余部分移一位。 @ateiob e.remove() 也是两个额外的方法调用、范围检查和对象返回(AbstractList.Itr.remove()ArrayList.remove(int) 内部) @julius 如果这样做:size = 0; elementData = new Object[10]; 其余的都将被垃圾回收,因为支持数组没有外部引用。【参考方案5】:

clear() 会更有效率。它只会删除每个项目。使用 removeAll(arraylist) 需要做更多的工作,因为它会在删除之前检查 arraylist 中的每个项目以查看它是否存在于 arraylist 中。

【讨论】:

【参考方案6】:

ArrayList.clear() 的时间复杂度为O(n)removeAll 的时间复杂度为O(n^2)

所以是的,ArrayList.clear 更快。

【讨论】:

【参考方案7】:

clear() 方法删除单个ArrayList 的所有元素。这是一个快速的操作,因为它只是将数组元素设置为null

AbstractCollection 继承的removeAll(Collection) 方法从您调用该方法的集合中删除参数集合中的所有元素。这是一个相对较慢的操作,因为它必须搜索所涉及的集合之一。

【讨论】:

我认为它只是将所有元素设置为空,而不是某些元素。如果不是这样,它是如何决定哪些元素应该设置为 null 的? @Farid 抱歉,我的英语在这里太不正式了。我确实是说它将所有元素设置为空。我会解决的!【参考方案8】:

clear() 会遍历底层 Array 并将每个条目设置为 null;

removeAll(collection) 将通过 ArrayList 检查集合和remove(Object) 如果它存在。

我想clear() 比 removeAll 快得多,因为它没有比较,等等。

【讨论】:

【参考方案9】:

Array => 一旦在运行时为 Array 变量分配空间,分配的空间就不能扩展或移除。

ArrayList => 这不是在arraylist 中的情况。 ArrayList 可以在运行时增长和缩小。 分配的空间可以在运行时最小化或最大化。

【讨论】:

这没有回答 ArrayList.clear() 和 ArrayList.removeAll() 之间的区别,而不是 Array 和 ArrayList 之间的区别。 这个答案是不必要的。这不是问题所在。

以上是关于ArrayList.clear() 和 ArrayList.removeAll() 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Java ArrayList clear() 函数

JAVA这个能分页吗? List<HashMap<String, String>> list = new ArrayList<HashMap<String, Str

Android ListView清除

Java Collections Framework 汇总

Array(0) 和 array = [] 有啥区别 [重复]

Array 和 Array.prototype