我试图理解为什么Java的ArrayDeque比Java的LinkedList更好,因为它们都实现了Deque接口。

我很少看到有人在代码中使用ArrayDeque。如果有人对ArrayDeque是如何实现的有更多的了解,这将是有帮助的。

如果我理解了它,我就会更有信心使用它。我不能清楚地理解JDK实现管理头部和尾部引用的方式。


当前回答

ArrayDeque和LinkedList都实现了Deque接口,但实现方式不同。

关键的不同点:

ArrayDeque类是Deque接口的可调整大小的数组实现,LinkedList类是列表实现 NULL元素可以添加到LinkedList中,但不能添加到ArrayDeque中 ArrayDeque在两端的添加和删除操作上比LinkedList更有效,LinkedList实现在迭代期间有效地删除当前元素 LinkedList实现比ArrayDeque使用更多的内存

因此,如果你不需要支持NULL元素,并且在两端添加/删除元素时寻找更少的内存和效率,ArrayDeque是最好的

更多细节请参考文档。

其他回答

ArrayDeque和LinkedList都实现了Deque接口,但实现方式不同。

关键的不同点:

ArrayDeque类是Deque接口的可调整大小的数组实现,LinkedList类是列表实现 NULL元素可以添加到LinkedList中,但不能添加到ArrayDeque中 ArrayDeque在两端的添加和删除操作上比LinkedList更有效,LinkedList实现在迭代期间有效地删除当前元素 LinkedList实现比ArrayDeque使用更多的内存

因此,如果你不需要支持NULL元素,并且在两端添加/删除元素时寻找更少的内存和效率,ArrayDeque是最好的

更多细节请参考文档。

I believe that the main performance bottleneck in LinkedList is the fact that whenever you push to any end of the deque, behind the scene the implementation allocates a new linked list node, which essentially involves JVM/OS, and that's expensive. Also, whenever you pop from any end, the internal nodes of LinkedList become eligible for garbage collection and that's more work behind the scene. Also, since the linked list nodes are allocated here and there, usage of CPU cache won't provide much benefit.

如果它可能是感兴趣的,我有一个证明,添加(追加)一个元素到ArrayList或ArrayDeque运行平摊常数时间;参考这个。

链接结构可能是最糟糕的结构,因为每个元素都有缓存缺失。最重要的是,它们会消耗更多的内存。

如果需要对两端进行添加/删除操作,ArrayDeque明显优于链表。随机访问每个元素也是O(1)循环队列。

链表唯一更好的操作是在迭代过程中删除当前元素。

所有批评LinkedList的人,想想其他在Java中使用List的人,大多数时候可能使用数组列表和LinkedList,因为他们在Java 6之前就已经使用了,因为这些是大多数书中作为开始教的。

但是,这并不意味着,我会盲目地站在LinkedList或ArrayDeque这一边。如果你想知道,看看下面Brian做的基准测试(存档)。

测试设置考虑:

每个测试对象是一个500字符的字符串。每个String在内存中是一个不同的对象。 测试数组的大小将在测试期间变化。 对于每个数组大小/队列实现组合,将运行100个测试,并计算每个测试的平均时间。 每个测试都包含用所有对象填充每个队列,然后将它们全部删除。 以毫秒为单位测量时间。

测试结果:

在10,000个元素以下,LinkedList和ArrayDeque测试的平均时间都低于1毫秒。 随着数据集越来越大,ArrayDeque和LinkedList平均测试时间之间的差异也越来越大。 在测试大小为9,900,000个元素时,LinkedList方法花费的时间比ArrayDeque方法长165%。

图:

导读:

If your requirement is storing 100 or 200 elements, it wouldn't make much of a difference using either of the Queues. However, if you are developing on mobile, you may want to use an ArrayList or ArrayDeque with a good guess of maximum capacity that the list may be required to be because of strict memory constraint. A lot of code exists, written using a LinkedList so tread carefully when deciding to use a ArrayDeque especially because it DOESN'T implement the List interface(I think that's reason big enough). It may be that your codebase talks to the List interface extensively, most probably and you decide to jump in with an ArrayDeque. Using it for internal implementations might be a good idea...

ArrayDeque访问一个元素的时间复杂度为O(1), LinkList访问最后一个元素的时间复杂度为O(N)。ArrayDeque不是线程安全的,所以手动同步是必要的,这样你就可以通过多个线程访问它,这样它们会更快。