ArrayList 与 HashSet 中的 removeAll()

removeAll() in ArrayList vs HashSet

我发现对于相当大的数组(超过 1000 个条目),方法 A.removeAll(B)HashSet 上比在 ArrayList 上快得多。

您是否知道这些方法是如何实现的,以及这如何解释这种差异?

一个集合(因此 HashSet 也是如此)最多包含 B 的一个元素,并且由于 HashSet 使用散列,因此定位和删除该元素非常有效。因此,整体复杂度应该是 O(1) 用于删除所有(即一个)B.

列表可以在任何位置包含任意数量的 B,因此删除所有 B 必须检查所有元素。总体复杂度为 O(n),因为必须检查每个元素是否为 B

编辑:

如果 B 表示一个 collection/array,即一组多个元素,您需要将上述复杂度乘以 B 的大小 m,所以您HashSet 会得到 O(m),列表会得到 O(n * m)

编辑 2:

请注意,如果您有一个排序列表,复杂性可能会降低到 O(log(n))O(log(n) * m)。为此,删除实际元素的代码必须 知道 列表已排序,但由于不能保证 ArrayList 已排序,因此无法进行优化。

基本上,两者的原因是这些特定实现试图为其各自的操作实现的时间复杂度。

ArrayList 移除方法的时间复杂度为 O(n - index) source from When to use LinkedList over ArrayList?

虽然 HashSet 的 remove 方法提供恒定的时间复杂度 O(1) source from Hashset vs Treeset