列表接口是泄漏抽象吗?


9

如果我有一个包含的变量,List则它可能包含许多不同类型的对象,例如ArrayListLinkedList。a LinkedList和an 之间的差异ArrayList非常大。这些方法的大O行为差异很大。例如,对进行排序List,然后使用它进行二进制搜索是完全可以的,ArrayList但对则没有任何意义LinkedList


“大O”是什么意思?
TulainsCórdova'13

Answers:


25

我不会这么说。

泄漏抽象是一种强迫您处理应该抽象掉的实现细节的方法。但是性能不同的实现之间总是不同的,因此,如果将其视为泄漏,则不会存在非泄漏的抽象。

如果声明某些内容List没有进一步的文档说明,则应该理解,根本不能保证性能,并且如果您要对性能进行任何敏感的工作,都应该对其进行复制并使用。

另外,不要忘记,还有一个更一般的接口,往往是足够的功能和不吸引你作出有关性能的许多假设:Collection


9
还有一个更一般的接口,这个接口的功能通常就足够了: Iterable
emory

预期不同实现之间的性能差异。例如,Vector和ArrayList之间存在差异,但是对LinkedList进行的get操作似乎很奇怪。
2013年

17

在某种程度上,所有非平凡的抽象都是泄漏的。就是说,我不确定在这里是否适用。:-)

抽象与行为有关。除非该行为指定了特定的性能(Java List并未指定),否则它是实现细节-即不相关。

Java不允许您为文档之外的接口指定最低性能,而且我不知道有哪种语言可以这样做-编译器很难验证它(不可能?)。如果要考虑性能,我可以看到几个选择:

  1. 在列表实例所属的类/接口中对其进行文档化。
  2. 创建一个新的界面-例如BinarySearchPerformantList(yuck!)-指定各种方法的性能要求。

选项2可能是更好的抽象,但是带有额外的开销。


1
+1。从技术上讲,列表是一个泄漏的抽象,但是对象也是如此,用于隐藏与equals用于比较对象有关的复杂性。
Neil 2013年

2
@Neil我认为这值得商......由于抽象没有提及性能,因此我认为在这种情况下它不会失败(正如我所说)。我想说的是,如果您正在考虑性能,则需要一个不同/较窄的抽象。编辑将提及。
vaughandroid

我想这取决于你隐藏的东西。使用的复杂性还是它的内存使用和实现方式?因为如果它是一个抽象类,那么这些复杂性中的一个或多个就会以一种或另一种方式被隐藏。
Neil 2013年

我玩了很多年,使用标记接口(如LinearSpace和)LogarithmicTime声明类(如)来实现选项2的变体public class BinarySearch : ISearchStrategy<T>, LogarithmicTime。其他类可以采用类似参数public T find<T, S>(IList<T> list, S strategy) where S : ISearchStrategy<T>, LogarithmicTime { }来强制执行性能约束。
卢卡斯

2
如果我们继续阅读Joel Spolsky的文章,我认为它在某种程度上是“漏水的”。请参阅文章中的以下引文:“如果您对公司的系统管理员不屑一顾,他们通过将您插入过载的集线器来惩罚您,那么只有部分IP数据包可以通过,TCP可以工作,但一切都会真的很慢”我认为这适用
Amish Programmer

4

在Java中,有一个RandomAccess接口,它被定义为一个具有通常恒定的随机访问时间(O(1)get,put等)的列表。如果您认为您的模块需要具有这些性能特征的列表,请考虑使用RandomAccess而不是List。如果您不需要进行更改(很少这样做),那么List可能不会那么容易。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.