该行为(某种程度上)记录在javadoc中:
此实现通过在每个集合上调用size方法来确定该集合和指定集合中的较小者。 如果此集合具有较少的元素
,则实现将对此集合进行迭代,依次检查迭代器返回的每个元素,以查看 其是否包含在指定的collection中
。如果包含此类内容,则使用迭代器的remove方法将其从此集合中删除。如果指定的集合具有较少的元素,则实现将迭代指定的集合,并使用此集合的remove方法从此集合中删除迭代器返回的每个元素。
实际上,当您致电时意味着什么
source.removeAll(removals);:
如果
removals
集合的大小小于source
,则调用的remove
方法HashSet
,这是快速的。如果
removals
集合的大小等于或大于source
,则将removals.contains
调用,这对于ArrayList来说很慢。
快速解决:
Collection<Integer> removals = new HashSet<Integer>();
请注意,存在一个与您所描述的非常相似的公开错误。底线似乎是它可能是一个较差的选择,但不能更改,因为它已在javadoc中进行了说明。
作为参考,这是
removeAll(在Java 8中-未检查其他版本)的代码:
public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); boolean modified = false; if (size() > c.size()) { for (Iterator<?> i = c.iterator(); i.hasNext(); ) modified |= remove(i.next()); } else { for (Iterator<?> i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { i.remove(); modified = true; } } } return modified;}


