Java下的ArrayDeque、Stack、LinkedList三种数据结构的区别
数据结构
由继承树看出,三者都是Collection的间接实现类。
ArrayDeque实现Deque接口,Stack继承于Vector,LinkedList实现Deque与List接口
底层数据存储方式
存储方式
Stack 长度为10的数组
ArrayDeque 长度为16的数组LinkedList链表
LinkedList 链表
线程安全
线程安全
Stack 线程同步
ArrayDeque 线程不同步
LinkedList 线程不同步
Deque
Deque是“双端队列的缩写”,Deque接口下都是双向的数据结构,如:LinkedList(链表、栈)、ArrayDeque(双向队列、栈)。二者都具备作为栈的能力。
ArrayDeque
基于数组实现,并且具有作为栈的能力!!!
构造方法
ArrayDuque<E> queue = new ArrayDeque<E>();
peek() 返回但不删除队头节点的值 等同于peekFirst()
peekFirst(); peek(); peekLast() 返回但不删除队末的值 peekLast(); add(E e) 进队 在队末加入元素 等同于addLast() queue.add(e); queue.addLast(e); addFirst(E e) 在队头加入元素 clone() 克隆一个相同的队列 ArrayDeque<E> queue2 = queue.clone(); isEmpty() 判断是否为空 Iterator() 返回这个队列的迭代器
//输出队列所有元素 Iterator<Integer> iterator = mem.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }
remove() 将队头的元素出队 等同于removeFirst()
remove(); removeFirst(); removeLast() 将队末的元素出队 removeLast(); size() 返回队列的长度 int size = queue.size(); toArray() 返回队列所有元素(从头到尾) E[] arr = queue.toArray(); pop() 删除并返回头元素的值 int res = stack.pop(); getFirst() 得到头元素 getLast() 得到尾元素
Deque / LinkedList的方法使用
必读
==注意:==看似相同的方法区别很大,使用时必须注意,比如add()方法和push()方法截然不同,前者用于构造队列,后者可以用来构造栈,两个方法的效果也不一样!!!
add 和 remove ** 是一对,源自Collection**;
offer和poll是一对,源自Queue;
push和pop是一对,源自Deque,其本质是栈(Stack类由于某些历史原因,官方已不建议使用,使用Deque代替);
offerFirst / offerLast 和 pollFirst ** / pollLast ** 是一对,源自Deque,其本质是双端队列。
而这些方法出现都在LinkedList / Deque 中,是由于它们的继承关系导致的。尤其需要注意的是:接口Deque是栈和双端队列这两种数据结构的集合体,Deque接口代替了Stack类;
公共方法
这些方法是各种数据结构都可以用的,不需要注意
size()
getFirst()
getLast()
方法
**add ** / remove源自集合,所以添加到队尾,从队头删除;
offer / poll源自队列(先进先出 => 尾进头出),所以添加到队尾,从队头删除;
push / pop源自栈(先进后出 => 头进头出),所以添加到队头,从队头删除;
offerFirst / **offerLast ** / pollFirst / pollLast源自双端队列(两端都可以进也都可以出),根据字面意思,offerFirst添加到队头,offerLast 添加到队尾,pollFirst从队头删除,pollLast从队尾删除。
总结:
add / offer / offerLast 添加队尾,三个方法等价;
push / offerFirst 添加队头,两个方法等价。
remove / pop / poll / pollFirst 删除队头,四个方法等价;
pollLast 删除队尾。
方法选择
虽说某几个方法等价,但是我们在使用的时候,建议根据用途来使用不同的方法,比如你想把 LinkedList 当做集合list,那么应该用add/remove,如果想用作队列,则使用offer/poll,如果用作栈,则使用push/pop,如果用作双端队列,则使用offerFirst/offerLast/pollFirst/pollLast。根据语义使用,就不会发生:我想删队尾,结果删了队头这种事了。
栈
栈的实现可以用Deque(常见的),也可以用LinkedList
push() 压栈
pop() 出栈
队列
offer() 入队
poll () 出队
双端队列
offerFirst() 添加到队头
offerLast () 添加到队尾
pollFirst () 删除队头
pollLast () 删除队尾
性能选择
通常情况下,不推荐使用Vector以及其子类Stack
频繁的插入、删除操作:LinkedList
频繁的随机访问操作:ArrayDeque
未知的初始数据量:LinkedList
感觉上,只要底层是数组的就比底层是链表的随机访问效率高,插入删除效率低
文章知识点与官方知识档案匹配,可进一步学习相关知识