如果我有一个包含的变量,List
则它可能包含许多不同类型的对象,例如ArrayList
或LinkedList
。a LinkedList
和an 之间的差异ArrayList
非常大。这些方法的大O行为差异很大。例如,对进行排序List
,然后使用它进行二进制搜索是完全可以的,ArrayList
但对则没有任何意义LinkedList
。
如果我有一个包含的变量,List
则它可能包含许多不同类型的对象,例如ArrayList
或LinkedList
。a LinkedList
和an 之间的差异ArrayList
非常大。这些方法的大O行为差异很大。例如,对进行排序List
,然后使用它进行二进制搜索是完全可以的,ArrayList
但对则没有任何意义LinkedList
。
Answers:
我不会这么说。
泄漏抽象是一种强迫您处理应该抽象掉的实现细节的方法。但是性能在不同的实现之间总是不同的,因此,如果将其视为泄漏,则不会存在非泄漏的抽象。
如果声明某些内容List
没有进一步的文档说明,则应该理解,根本不能保证性能,并且如果您要对性能进行任何敏感的工作,都应该对其进行复制并使用。
另外,不要忘记,还有一个更一般的接口,往往是足够的功能和不吸引你作出有关性能的许多假设:Collection
。
Iterable
。
在某种程度上,所有非平凡的抽象都是泄漏的。就是说,我不确定在这里是否适用。:-)
抽象与行为有关。除非该行为指定了特定的性能(Java List
并未指定),否则它是实现细节-即不相关。
Java不允许您为文档之外的接口指定最低性能,而且我不知道有哪种语言可以这样做-编译器很难验证它(不可能?)。如果要考虑性能,我可以看到几个选择:
BinarySearchPerformantList
(yuck!)-指定各种方法的性能要求。选项2可能是更好的抽象,但是带有额外的开销。
equals
用于比较对象有关的复杂性。
LinearSpace
和)LogarithmicTime
声明类(如)来实现选项2的变体public class BinarySearch : ISearchStrategy<T>, LogarithmicTime
。其他类可以采用类似参数public T find<T, S>(IList<T> list, S strategy) where S : ISearchStrategy<T>, LogarithmicTime { }
来强制执行性能约束。
在Java中,有一个RandomAccess接口,它被定义为一个具有通常恒定的随机访问时间(O(1)get,put等)的列表。如果您认为您的模块需要具有这些性能特征的列表,请考虑使用RandomAccess
而不是List
。如果您不需要进行更改(很少这样做),那么List可能不会那么容易。
您是正确的,列表是一个泄漏的抽象。STL使用概念的思想来建模此特定问题。为了使用您的示例,ArrayList
模型为Random Access Iterator建模,而LinkedList为Forward Iterator建模。不同的概念具有不同的性能要求,这使其适用于不同的算法。