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] = null
和e.remove()
之间的区别重要吗?
没有理智的理由使用arrList.removeAll(arrList)
而不是arrList.clear()
。 arrList1.removeAll(arrList2)
是另一回事。
如果 removeAll() 的实现只从这一行开始,那么整个讨论会更有趣! if (c == this && !isEmpty()) clear(); return true;
。我必须将此作为补丁提交给 OpenJDK! ;-)
【参考方案1】:
Clear 更快,因为它不会遍历要删除的元素。该方法可以假设所有元素都可以删除。
Remove all
并不一定意味着删除列表中的所有元素,只有那些作为参数提供的元素应该被删除。因此,需要更多的努力来保留那些不应该删除的内容。
澄清
“循环”是指它不必检查是否应该保留元素。它可以设置对null
的引用,而无需搜索提供的要删除的元素列表。
Clear
比 deleteall
快。
【讨论】:
我很确定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这个能分页吗? List<HashMap<String, String>> list = new ArrayList<HashMap<String, Str