为什么ArrayList
通常不会被实现为双端,这将支持前端和后端的快速分期插入?
使用后者比前者更不利吗?
(我不只是谈论Java - 我没有看到双端数组列表是任何其他语言的默认值,但Java只是一个很好的例子。)
*编辑:我最初称它们为“阵列deques”,但这对我来说是一种误解;我不是在谈论队列,而是在谈论双端阵列。
答案 0 :(得分:5)
ArrayList很简单;条目从0开始,你可以在最后添加东西(这可能会延长数组),但列表中的条目#X始终是backing_array[X]
。
ArrayDeque会更复杂;除了必须跟踪序列的开始(因为它不再保证从0开始,除非你想要O(N)转换/取消),你还必须担心另一端是“空”。额外的复杂性需要付出代价;在更常见的情况(列表)中,RTL仍然必须在双端队列中进行所有必要的检查和索引数学运算,从而减慢应用程序的速度。条目#X变为backing_array[start+X]
,边界检查也有额外的数学运算。
因此,除非你真的需要双端队列功能,否则坚持使用列表会更简单,更有效率,至少在你搞乱阵列的时候。
答案 1 :(得分:1)
当你想以FIFO或LIFO方式访问数据时使用deque,它们的公共接口既不提供获取第n个元素的方法,你应该手工完成,如果你看看Java Deque here,你知道没有提供第n种方法。当您需要索引任何数据组时,这应该足以避免使用它。
好的,你可以实现一个数组deque而不是普通的数组,但是这会增加在你需要时应该考虑的功能,而不是默认情况下。否则,你可以证明使用更复杂的数据结构来解决简单问题是正确的。
恕我直言,这也是现在阵列之间协同作用的问题,以及当您编写更接近机器的代码时如何实施/管理它们。
答案 2 :(得分:0)
在Java中,ArrayDeque不实现List。我不确定为什么不这样做。
答案 3 :(得分:0)
正常的ArrayList
实现是代码的正常首选集合类型,只需要它可以重复添加项目然后从中读取项目。该类型提供了更多的功能,省略其中一些可能会增强主要使用情况下类型的功能,但是如果ArrayList
操作是在{{1}}操作,则必须在整个Universe中花费的额外CPU时间总量。即使慢1%也会很重要。
此外,目前尚不清楚对双端数组列表的索引访问应该如何表现,因为有两种合理的行为模型:它可以指定从低编号端添加或删除项应该改变编号所有现有项目,或者它可以指定在项目0之前插入的项目的索引将为-1(所有现有索引将保持不变)。在项目0之前添加超过2 ^ 32个项目(同时从另一端移除足够的项目以避免内存不足)将添加项目MIN_INT,然后是项目MAX_INT,然后是MAX_INT-1等。这样的界面可能很笨拙某些方面,但在其他方面可能非常好(例如,实现可以允许作者线程和读取器线程同时进行索引访问,这些操作在相反的两端,因为想要操作元素547的编写者不必担心它所用的时间会使感兴趣的元素转移到插槽#548)。
当然有各种双端集合类型的用途,但这并不意味着添加双端功能会为常见用例添加任何值。