前言
最近在刷算法,其中不乏需要用到栈和队列这样数据结构,就需要学习一下Java怎么用现成的轮子的,结果发现具体的实现有各种,有用ArrayList来实现栈的,也有用Stack来实现的。正好借此机会来复习(水)一下Java容器方面的知识点。
一、关于容器
Java将集合接口与实现分离:
Java6中引入了双端队列Deque接口
循环数组 ArrayDeque和链表 LinkedListt 实现了该接口。
遗留的容器类
在集合框架出现之前已经存在大量“遗留的”容器类,官方现在已经不建议用
不过目前这些类已经集成到集合框架中:
二、LinkedList作队列、作栈
下面两道lc题虽然简单,但可以帮助我们认清LinkedList中的栈与队列
LC232:用 栈 实现 队列
官方2019-06月题解用的是Stack 然后下面有人评论说
因为stack继承了vector类,官方文档现在已经不建议用stack了而是建议用deque实现栈,所以我用了deque,LinkedList的addLast和removeLast
官方2021-03月题解用了LinkedList作为双栈 实现了队列
将数据放入用的是LinkedList的pop和push方法,于是我去看了一下
Deque<Integer> inStack = new LinkedList<>()
public void push(E e) {
addFirst(e);
}
public E pop() {
return removeFirst();
}
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
所以上文别人直接调用addLast和removeLast同样也能实现栈的入栈出栈操作,都是操作一端
LC225. 用 队列 实现 栈
offer也提供了offerFirst,offerLast方法
public boolean offer(E e) {
return add(e);//直接调用add
}
public boolean add(E e) {
linkLast(e); //默认在尾部追加
return true;
}
public E poll() {
final Node<E> f = first; //默认在头部出队
return (f == null) ? null : unlinkFirst(f);
}
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
总结
LinkedList很灵活,可以通过调用它不同的方法来达到队列/栈的效果:
- LinkedList当作栈来用 ,就用push和pop等方法
- LinkedList当作队列来用,就用offer和poll等方法
- LinkedList当作普通链表来用,就直接用add和remove等
附:
集合框架中的类
API文档中有Abstract开头的类,这些是为类库实现者设计的,
如果要实现自己的类库,扩展AbstractQueue类要比实现Queue接口中的所有方法轻松。
具体集合
…
集合类的基本接口Collection
Collection接口路就是实现了iterator方法
现在遍历用for each更简练 编译器会简单的将for each转为带有迭代器的循环
(1.8+ 也可以lambda表达式) iterator.forEachRemaining(element -> do…);
优先队列(priority queue) 堆,实现了Comparable接口 java.util.PriorityQueue
…