在Joshua Bloch的《 Effective Java》一书中,讨论了一个类如何提供“明智选择的 protected 方法”作为其内部工作的钩子(Hook)。
然后作者引用了 AbstractList.removeRange()
中的文档:
我的问题是,重写此方法如何提高性能(不仅仅是简单地不重写它)?谁能举一个例子吗?
最佳答案
让我们举一个具体的例子-假设您的实现由动态数组支持(例如ArrayList
的工作方式)。现在,假设您要删除[开始,结束)范围内的元素。 removeRange
的默认实现是通过使迭代器定位start
,然后调用remove()
适当的次数来工作的。
每次调用remove()
时,动态数组实现都必须对start + 1
位置处的所有元素进行混洗,并向前回退一个点以填充已删除元素中剩余的空白。这可能会花费时间O(n),因为可能所有数组元素都可能需要改组。这意味着,如果您要从列表中删除总共k
元素,那么天真的方法将花费O(kn)的时间,因为您要执行O(n)k次。
现在考虑一种更好的方法:将end
位置的元素复制到start
位置,然后将end + 1
元素复制到start + 1
位置,依此类推,直到复制所有元素。这要求您仅执行O(n)的总工作,因为每个元素最多只能移动一次。与朴素算法给出的O(kn)方法相比,这是一个巨大的性能改进。因此,重写removeRange
以使用此更有效的算法可以大大提高性能。
希望这可以帮助!