我试图理解为什么Java的ArrayDeque比Java的LinkedList更好,因为它们都实现了Deque接口。
我很少看到有人在代码中使用ArrayDeque。如果有人对ArrayDeque是如何实现的有更多的了解,这将是有帮助的。
如果我理解了它,我就会更有信心使用它。我不能清楚地理解JDK实现管理头部和尾部引用的方式。
我试图理解为什么Java的ArrayDeque比Java的LinkedList更好,因为它们都实现了Deque接口。
我很少看到有人在代码中使用ArrayDeque。如果有人对ArrayDeque是如何实现的有更多的了解,这将是有帮助的。
如果我理解了它,我就会更有信心使用它。我不能清楚地理解JDK实现管理头部和尾部引用的方式。
当前回答
ArrayDeque访问一个元素的时间复杂度为O(1), LinkList访问最后一个元素的时间复杂度为O(N)。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比LinkedList好。他们是不同的。
ArrayDeque平均比LinkedList快。但是对于添加一个元素,ArrayDeque需要平摊常数时间,LinkedList也需要常数时间。
对于时间敏感的应用程序,需要所有操作花费常数时间,应该只使用LinkedList。
ArrayDeque的实现使用数组并需要调整大小,有时,当数组已满并且需要添加一个元素时,将花费线性时间来调整大小,从而导致add()方法花费线性时间。如果应用程序对时间非常敏感,这可能是一场灾难。
关于Java实现这两种数据结构的更详细的解释可以在普林斯顿大学在Coursera上提供的“算法,第一部分”课程中找到,该课程由Wayne和Sedgewick教授。该课程对公众免费开放。
详细信息将在“第二周”的“堆栈和队列”部分的视频“调整数组大小”中解释。
虽然ArrayDeque<E>和LinkedList<E>都实现了Deque<E>接口,但是ArrayDeque基本上使用对象数组E[]来保持其对象中的元素,因此它通常使用索引来定位头部和尾部元素。
总之,它就像Deque一样工作(使用所有Deque的方法),但是使用数组的数据结构。至于哪一个更好,取决于你如何和在哪里使用它们。
链接结构可能是最糟糕的结构,因为每个元素都有缓存缺失。最重要的是,它们会消耗更多的内存。
如果需要对两端进行添加/删除操作,ArrayDeque明显优于链表。随机访问每个元素也是O(1)循环队列。
链表唯一更好的操作是在迭代过程中删除当前元素。
ArrayDeque访问一个元素的时间复杂度为O(1), LinkList访问最后一个元素的时间复杂度为O(N)。ArrayDeque不是线程安全的,所以手动同步是必要的,这样你就可以通过多个线程访问它,这样它们会更快。