在子类中使用AbstractList类的removeRange方法有什么用

时间:2015-03-31 12:33:12

标签: java list effective-java

在Effective Java中,声明

  

removeRange方法对List的最终用户不感兴趣   实现。它仅用于使子类更容易   为子列表提供快速清晰的方法。在没有的情况下   removeRange方法,子类必须使用二次方法   在子列表上调用clear方法或重写时的性能   从头开始整个子列表机制 - 不是一件容易的事!

请查看此link。最后一段。它表示在 removeRange 方法的缺席中,子类必须使用二次性能

请解释为什么作者这样说。

2 个答案:

答案 0 :(得分:1)

  

如果没有removeRange方法,当在子列表上调用clear方法时,子类必须处理二次性能

作者假设实现必须为范围的每个元素调用remove。在一些实现中,例如ArrayList s,remove必须在移除元素之后复制所有内容,其具有O(n)复杂度。假设范围大小为r,则循环实现的总体复杂度为O(n * r),这是二次的。

特定于removeRange的{​​{1}}实现具有O(n)复杂度,因为您可以在单个循环中将其复制到新位置。

答案 1 :(得分:1)

AbstractList已提供subList(int from, int to)的默认实施。此默认子列表的clear()方法只是在其父列表中调用removeRange(...)

如果没有removeRange(...),子列表必须使用迭代器,重复调用next()remove()。但是,通过Iterator.remove()删除元素可能具有线性性能 - 例如每次删除元素时,ArrayList必须左移其内部数组中的所有后续元素。重复调用线性方法会产生二次性能。

注意removeRange(...)中的AbstractList实现默认使用迭代器。因此,子类应覆盖它以提供更高性能的实现(如果可用)。

优势:为了优化性能,子类只需实现removeRange,并且可以保留subList(...)的默认实现。