在Effective Java中,声明
removeRange方法对List的最终用户不感兴趣 实现。它仅用于使子类更容易 为子列表提供快速清晰的方法。在没有的情况下 removeRange方法,子类必须使用二次方法 在子列表上调用clear方法或重写时的性能 从头开始整个子列表机制 - 不是一件容易的事!
请查看此link。最后一段。它表示在 removeRange 方法的缺席中,子类必须使用二次性能。
请解释为什么作者这样说。
答案 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(...)
的默认实现。