一、概述
版本: JDK 1.8
队列
是一种特殊的线性表,只允许在表的前面 (队头) 进行删除操作,而在表的后面 (队尾) 进行插入操作。即最先插入的元素最先被删除;因此队列又称为 先进先出(FIFO)
的线性表。
另一种数据结构是 栈
,它的特点是 后入先出(LIFO)
,即最后进入的元素最先出来。
二、类图
三、源码分析
主要从 Queue、Deque、BlockingQueue
三个类来分析源码;
3.1 类Queue
接口类
Queue
是整个队列的基类,定义了队列的基本操作 :入队、出队、获取对头元素
- Insert:从队尾入队
- Remove:从队头出队
- Examine:获取队头的元素
对于每一种操作,Queue都定义了两种方法:
- 其中一个方法在操作失败时,会抛出异常;
- 另一个方法在操作失败时会返回一个特定的值,如 null 或是 false;
// 队列的基类,定义了队列的基本操作行为;
public interface Queue<E> extends Collection<E> {
// 向队尾添加元素;
boolean add(E e); //当队列空间不足时,则抛出IllegalStateException异常;
boolean offer(E e);
// 从队首移除元素;
E remove(); // 当队列为空时,则抛出异常;
E poll(); // 当队列为空时,则返回null;
// 从队首获取元素,但不移除;
E element();// 当队列为空时,则抛出异常;
E peek(); // 当队列为空时,则返回null;
}
3.2 类Deque
接口类
Deque
是双端队列,是一种具有 队列 和 栈 的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。
由于 Deque 是双端队列,因此可以从 队头 或者 队尾 进行基本操作:
- 队头:插入、删除、检索元素;
- 队尾:插入、删除、检索元素;
同Queue一样,对于每一种操作,Deque也定义了两种方法:
- 一种是在满队列或者空队列的操作元素时,会抛出异常;
- 另一种在满队列或者空队列的操作元素时,会返回 null 或是 false;
// 继承于Queue,就具备了Queue的三种基本操作;
public interface Deque<E> extends Queue<E> {
// 添加元素,如果添加不成功,会抛出IllegalStateException异常;
void addFirst(E e); //添加到队头;
void addLast(E e); //添加到队尾;
// 添加元素,不抛异常;
boolean offerFirst(E e); //添加到队头;
boolean offerLast(E e); //添加到队尾;
// 移除元素,抛异常;
E removeFirst(); //从队首移除;
E removeLast(); //从队尾移除;
// 移除元素,不抛异常;
E pollFirst(); //从队首移除;
E pollLast(); //从队尾移除;
// 获取元素,但不移除,若为空队列时,抛出异常;
E getFirst(); //获取队首元素
E getLast(); //获取队尾元素
// 获取元素,但不移除,若为空队列时,不抛出异常;
E peekFirst(); //获取队首元素
E peekLast(); //获取队尾元素
// 移除元素
boolean removeFirstOccurrence(Object o); //从队首开始,移除第一个遇到的与指定元素相同的元素;
boolean removeLastOccurrence(Object o); //从队尾开始,移除第一个遇到的与指定元素相同的元素;
// ***** Queue methods *****
// 以下方法继承自Queue接口
boolean add(E e); //同 addLast(E e)
boolean offer(E e); //同 offerLast(E e)
E remove(); //同 removeFirst()
E poll(); //同 pollFirst()
E element(); //同 getFirst()
E peek(); //同 peekFirst()
// ***** Stack methods *****
// 定义栈的两种基本操作
void push(E e); //同 addFirst()
E pop(); //同 removeFirst()
// ***** Collection methods *****
// 以下属于集合基类(Collection)的方法
boolean remove(Object o);
boolean contains(Object o);
public int size();
Iterator<E> iterator();
Iterator<E> descendingIterator();
}
3.3 类BlockingQueue
同Queue一样,对于每一种操作,BlockingQueue也定义了两种方法:
- 一种是在满队列或者空队列的操作元素时,会抛出异常;
- 另一种在满队列或者空队列的操作元素时,会返回 null 或是 false;
// 阻塞队列
public interface BlockingQueue<E> extends Queue<E> {
// ******** 添加元素 **********
//如果队列暂无空间,则添加失败,并抛出 IllegalStateException 异常;
boolean add(E e);
//如果队列暂无空间,则添加失败(不抛异常),返回false;
boolean offer(E e);
//如果队列暂无空间,,则调用此方法的线程被阻断,直到队列有空间后再继续执行;
void put(E e) throws InterruptedException;
//如果队列暂无空间,则在指定的等待时间内,当前线程阻塞;当等待时间结束后,队列空间仍然不足时,则返回false;
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
// ********** 移除元素 ************
//从队首获取元素:若队列为空时,则阻断进入等待状态直到队列有新元素被加入;
E take() throws InterruptedException;
//从队首获取元素:若在指定时间内,能从队列中获取元素,则返回获取到的元素;否则表示获取元素超时,返回失败;
E poll(long timeout, TimeUnit unit) throws InterruptedException;
// 一次性从队列中获取所有可用的数据对象;
int drainTo(Collection<? super E> c);
// 一次性从队列中获取指定个数的元素集;
int drainTo(Collection<? super E> c, int maxElements);
// 返回当前队列剩余空间;
int remainingCapacity();
boolean remove(Object o);
public boolean contains(Object o);
}
四、小结
队列分为 阻塞队列 和 非阻塞队列。
队列的操作分为 队尾添加元素 和 队首移除元素