我试图理解为什么Java的ArrayDeque比Java的LinkedList更好,因为它们都实现了Deque接口。
我几乎看不到有人在他们的代码中使用ArrayDeque。如果有人对ArrayDeque的实现方式有了更多的了解,那将是有帮助的。
如果我理解它,我会更自信地使用它。对于JDK实现管理头和尾引用的方式,我不清楚。
我试图理解为什么Java的ArrayDeque比Java的LinkedList更好,因为它们都实现了Deque接口。
我几乎看不到有人在他们的代码中使用ArrayDeque。如果有人对ArrayDeque的实现方式有了更多的了解,那将是有帮助的。
如果我理解它,我会更自信地使用它。对于JDK实现管理头和尾引用的方式,我不清楚。
Answers:
链接结构可能是最糟糕的结构,要在每个元素上进行缓存未命中来进行迭代。最重要的是,它们消耗了更多的内存。
如果您需要两端的添加/删除,则ArrayDeque明显优于链接列表。对于循环队列,每个元素的随机访问也是O(1)。
链表的唯一更好的操作是在迭代过程中删除当前元素。
LinkedList
实现List
而ArrayDeque
没有。这意味着,LinkedList
有方法,如indexOf
或remove(int)
同时ArrayDeque
也没有。有时可能很重要。
所有批评a的人LinkedList
都会想到List
在Java中使用过的其他每个人, ArrayList
而且在LinkedList
大多数情况下,是因为他们早于Java 6,并且因为这些是大多数书籍中开始学习的东西。
但这并不意味着,我会盲目站在LinkedList
或ArrayDeque
的一边。如果您想知道,请看Brian所做的以下基准测试。
测试设置考虑:
- 每个测试对象都是一个500个字符的字符串。每个字符串是内存中的不同对象。
- 在测试期间,测试阵列的大小将有所不同。
- 对于每个阵列大小/队列实现组合,将运行100个测试,并计算平均每次测试时间。
- 每个测试包括用所有对象填充每个队列,然后将其全部删除。
- 以毫秒为单位测量时间。
测试结果:
- 低于10,000个元素时,LinkedList和ArrayDeque测试的平均值均在1 ms以下。
- 随着数据集变大,ArrayDeque和LinkedList平均测试时间之间的差异也变大。
- 在990万个元素的测试大小下,LinkedList方法比ArrayDeque方法花费了约165%的时间。
图形:
带走:
ArrayList
或ArrayDeque
很好地估计可能需要该列表的最大容量。LinkedList
在决定使用ArrayDeque
特别代码时要谨慎地使用代码编写,因为它没有实现List
接口(我认为这足够大)。可能是您的代码库与List接口进行了广泛的对话,最有可能的是,您决定跳入ArrayDeque
。将其用于内部实现可能是一个好主意...ArrayDeque和 LinkedList正在实现Deque接口,但实现方式有所不同。
主要区别:
所述ArrayDeque类是的可调整大小的数组实现的Deque接口和链表类是列表实现
可以将NULL元素添加到LinkedList,但不能添加到ArrayDeque中
ArrayDeque比LinkedList更有效对于两端的添加和删除操作,,LinkedList实现对于在迭代过程中删除当前元素非常有效。
该链表实现消耗比更多的内存ArrayDeque
因此,如果您不必支持NULL元素&&寻找较少的内存,并且&&在两端添加/删除元素的效率都很高, ArrayDeque是最好的
有关更多详细信息,请参考文档。
header.previous.element
)。由于后备阵列始终会调整为下一个2的幂,因此“内存效率”声明也可能会受到挑战。
Iterator
访问最后一个元素时,两个类的操作均为O(N)。使用公共Deque
接口时,两个类的最后一个访问元素都是O(1)。无论您采用哪种观点,将O(1)归因于ArrayDeque
O(N)LinkedList
都是错误的。
并非总是如此。
例如,在以下情况下,linkedlist
其性能要比ArrayDeque
根据leetcode 103 更好。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> rs=new ArrayList<>();
if(root==null)
return rs;
// 👇 here ,linkedlist works better
Queue<TreeNode> queue=new LinkedList<>();
queue.add(root);
boolean left2right=true;
while(!queue.isEmpty())
{
int size=queue.size();
LinkedList<Integer> t=new LinkedList<>();
while(size-->0)
{
TreeNode tree=queue.remove();
if(left2right)
t.add(tree.val);
else
t.addFirst(tree.val);
if(tree.left!=null)
{
queue.add(tree.left);
}
if(tree.right!=null)
{
queue.add(tree.right);
}
}
rs.add(t);
left2right=!left2right;
}
return rs;
}
}
ArrayDeque用于访问元素的时间复杂度为O(1),而LinkList的时间复杂度为O(N)以访问最后一个元素。ArrayDeque不是线程安全的,因此需要手动同步,以便您可以通过多个线程访问它,因此它们更快。
LinkedList
在Java 中引用Collection
,则它是双向链接的,并且可以快速访问头部和尾部,因此访问最后一个元素也需要O(1)。