为什么典型的Array List实现不是双端的?

为什么ArrayList通常不实现双端,这将支持前端和后端的快速分期插入?

使用后者比前者更不利吗?

(我不只是谈论Java – 我没有看到双端数组列表是任何其他语言的默认值,但Java只是一个很好的例子。)


*编辑:我最初称它们为“arraysdeques”,但这对我来说是一种误解; 我不是在谈论队列,而是双端arrays表。

ArrayList很简单; 条目从0开始,你可以在最后添加东西(这可能会延长数组),但列表中的条目#X总是backing_array[X]

ArrayDeque会更复杂; 除了必须跟踪序列的开始(因为它不再保证从0开始,除非你想要O(N)转换/取消),你还必须担心另一端是“空”。 额外的复杂性需要付出代价; 在更常见的情况下(列表),RTL仍然必须在双端队列中进行所有必要的检查和索引数学运算,从而减慢应用程序的速度。 条目#X变为backing_array[start+X] ,并且边界检查也有额外的数学运算。

因此,除非你真的需要dequefunction,否则坚持列表会更简单,更有效,至少在你搞乱数组的时候。

只有当你想以FIFO或LIFO方式访问数据时才使用deque,它们的公共接口既不提供获取第n个元素的方法,你应该手工完成,事实上如果你看一下Java Deque 在这里 ,您了解没有提供第n种方法。 当您需要索引任何数据组时,这应该足以避免使用它。

好的,你可以实现一个数组deque而不是一个普通的数组,但是这会增加在你需要时应该考虑的function,而不是默认情况下。 否则,你可以certificate使用更复杂的数据结构来解决简单问题是正确的。

恕我直言,这也是现在arrays之间协同作用的问题,以及当您编写更接近机器的代码时如何实现/管理它们。

在Java中,ArrayDeque不实现List。 我不确定为什么不这样做。

正常的ArrayList实现是代码的常规集合类型,它只需要它可以重复添加项目然后从中读取项目。 该类型提供了更多的function,省略其中一些可能会增强主要使用情况下类型的function,但如果ArrayList操作甚至慢1%,则必须在整个Universe中花费的额外CPU时间总量会很重要的。

此外,还不清楚对双端数组列表的索引访问应该如何表现,因为有两种合理的行为模型:它可以指定从低编号端添加或删除项目应该更改所有现有项目的编号,或者它可以指定在项目0之前插入的项目的索引将为-1(所有现有索引将保持不变)。 在项目0之前添加超过2 ^ 32个项目(同时从另一端移除足够的项目以避免内存不足)将添加项目MIN_INT,然后是项目MAX_INT,然后是MAX_INT-1等。这样的界面可能很笨拙某些方法,但在其他方面可能非常好(例如,实现可以允许编写器线程和读取器线程同时进行索引访问,这些操作在相反的两端,因为想要操作元素547的编写者不必担心它所做的时间,感兴趣的元素将转移到插槽#548)。

当然有各种双端集合类型的用途,但这并不意味着添加双端function会为常见用例添加任何值。