队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。
LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。
本文也将围绕LinkedList进行分析,示例代码
Queue<Integer> queue = new LinkedList<>();
boolean add = queue.add(1);
Integer element = queue.element();
boolean offer = queue.offer(2);
Integer peek1 = queue.peek();
Integer poll = queue.poll();
Integer remove = queue.remove();
// 添加元素
public boolean add(E e) {
linkLast(e);
return true;
}
// 往链表最后添加
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
// 当链表为空时,将新创建的node 作为第一个节点,否则做为其后驱节点,并将size ++
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
// 返回元素的第一个节点
public E element() {
return getFirst();
}
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
其底层还是调用的add方法
public boolean offer(E e) {
return add(e);
}
返回第一个元素但是不删除
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
返回第一个元素并删除(不是空队列时删除)
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
// 将第一个元素置为null,当first的next 为null 将last也置为null
// 否则将first next 的prev 置为null 即将next 做为第一个节点
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
// 其实底部和poll 类似
public E remove() {
return removeFirst();
}
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
这里我可以发现 LinkeList 不是线程安全的,当我们需要使用线程安全的队列该如何做呢?当然JDK 自带了我们可以使用ArrayBlockingQueue
, 下一篇我们将讲解ArrayBlockingQueue