概述
功能:该类提供了Queue
接口的基础框架
开始版本:JDK 1.5
注意:
1. 本类为抽象
类
2. 可以存放相同元素,但不能存放null
3. 数据结构:顺序队列、链队列
4. 本类不同于其他集合,本类有两组增删查的方法,分别是add
/offer
(增),element
/peek
(查首位元素),remove
/poll
(删),区别为前者遇见队列满、队列为空会抛异常,而后者则返回false
、null
、null
,不会抛出异常并可以用于判断
5. 本方法没有单独重写toString()
方法,使用的是AbstractCollection
的toString()
方法
6. 本方法及实现/继承的接口均没有重写hashCode()
和equals()
方法,直接比较内容相同的两个不同队列返回结果为false
,如需返回为true
需重写这两个方法
常见队列具体实现类:
1. PriorityQueue
(优先级队列,不一定先进先出,与元素有关,非堵塞队列,非线程安全)
2. ConcurrentLinkedQueue
(链队列,非堵塞,线程安全)
3. ArrayBlockingQueue
(堵塞队列,线程安全)
4. LinkedBlockingQueue
(链队列,堵塞队列,线程安全)
5. PriorityBlockingQueue
(优先级队列,堵塞队列,线程安全)
6. DelayQueue
(优先级队列,不一定先进先出,与元素有关,堵塞队列,线程安全,有延迟期)
7. SynchronousQueue
(容量为0不储存元素,堵塞队列,线程安全)
8. LinkedBlockingDeque
(链队列,堵塞队列,线程安全、双端)
实现接口:java.util.Queue
继承类:java.util.AbstractCollection
所在包:java.util
类声明:
public abstract class AbstractQueue<E> extends AbstractCollection<E> implements Queue<E> {}
框架图:
方法
构造器
// 唯一构造器
protected AbstractQueue() {}
公有方法
01.新增元素 add(E e)
参数:e
—— 要新增的元素
注意:本方法先调用Queue
接口的offer(E e)
新增,新增失败(无空间)会返回false
,此时本方法直接抛出IllegalStateException
异常
// 源码
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
// 正常示例
@Test
void contextLoads() {
// 需注意 PriorityQueue 和 ConcurrentLinkedQueue 是非堵塞队列,创建时设置了大小
// 超过也仍然可以自带扩容存入,此处使用ArrayBlockingQueue,该队列时堵塞队列
Queue arrayBlockingQueue = new ArrayBlockingQueue(2);
arrayBlockingQueue.add(1);
arrayBlockingQueue.add(0);
arrayBlockingQueue.add(3);
// java.lang.IllegalStateException: Queue full
System.out.println(arrayBlockingQueue.element());
}
02.移除当前队首元素 remove()
注意:本方法先调用Queue
接口的poll()
移除,移除失败(队列为空)会返回null
,此时本方法直接抛出NoSuchElementException
异常
// 源码
public E remove() {
E x = poll();
if (x != null)
return x;
else
throw new NoSuchElementException();
}
// 示例:队列为空
@Test
void contextLoads() {
Queue priorityQueue = new PriorityQueue(2);
// null
System.out.println(priorityQueue.poll());
Queue priorityQueue1 = new PriorityQueue(2);
// java.util.NoSuchElementException
System.out.println(priorityQueue1.remove());
}
// 正常示例
@Test
void contextLoads() {
// 需注意PriorityQueue是优先级队列,不一定是先进先出,此处使用ConcurrentLinkedQueue
Queue concurrentLinkedQueue = new ConcurrentLinkedQueue();
concurrentLinkedQueue.add(1);
concurrentLinkedQueue.add(0);
concurrentLinkedQueue.add(3);
concurrentLinkedQueue.poll();
// [0, 3]
System.out.println(concurrentLinkedQueue);
}
03.查看当前队首元素 element()
注意:本方法先调用Queue
接口的peek()
查询,未查询到(队列为空)会返回null
,此时本方法直接抛出NoSuchElementException
异常
// 源码
public E element() {
E x = peek();
if (x != null)
return x;
else
throw new NoSuchElementException();
}
// 示例:队列为空
@Test
void contextLoads() {
Queue priorityQueue = new PriorityQueue(2);
// null
System.out.println(priorityQueue.peek());
Queue priorityQueue1 = new PriorityQueue(2);
// java.util.NoSuchElementException
System.out.println(priorityQueue1.element());
}
// 正常示例
@Test
void contextLoads() {
// ConcurrentLinkedQueue:先进先出
Queue concurrentLinkedQueue = new ConcurrentLinkedQueue();
concurrentLinkedQueue.add(1);
concurrentLinkedQueue.add(0);
concurrentLinkedQueue.add(3);
concurrentLinkedQueue.poll();
// 此处元素1出队,下一个是0 【输出0】
System.out.println(concurrentLinkedQueue.element());
// 需注意PriorityQueue是优先级队列,不一定是先进先出
PriorityQueue<Object> queue = new PriorityQueue<>();
queue.add(1);
queue.add(0);
queue.add(3);
queue.poll();
// 此处元素0出队,按优先级下一个是0 【输出1】
System.out.println(queue.element());
}
04.清空队列 clear()
说明:调用Queue
接口的poll()
一个个元素移除,根据返回值是否为null
判断是否全部移除
// 源码
public void clear() {
while (poll() != null)
;
}
// 示例
@Test
void contextLoads() {
Queue priorityQueue = new PriorityQueue(2);
priorityQueue.add(1);
priorityQueue.add(2);
// [1, 2]
System.out.println(priorityQueue);
priorityQueue.clear();
// []
System.out.println(priorityQueue);
}
05.将指定集合全部元素存入队列 addAll(Collection<? extends E> c)
参数:c
—— 要存入的集合
注意:
1. 指定集合为null
或就是此队列本身时会抛出异常
2. 本方法调用的是add(E e)
方法不是offer(E e)
,对于堵塞队列,若队列已满会抛出异常
3. 若指定集合中有元素为null
,调用本方法也会抛出异常
4. 需要在调用时校验指定集合的类型与队列是否一致,不一致且不能转换也会抛出异常
// 源码
public boolean addAll(Collection<? extends E> c) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
// 示例:类型不同
@Test
void contextLoads() {
Queue priorityQueue = new PriorityQueue(2);
priorityQueue.add(1);
priorityQueue.add(2);
// [1, 2]
System.out.println(priorityQueue);
List list = new ArrayList();
list.add("1");
list.add("2");
// [1, 2]
System.out.println(list);
// java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
priorityQueue.addAll(list);
System.out.println(priorityQueue);
}
// 示例:集合存在null值
@Test
void contextLoads() {
Queue priorityQueue = new PriorityQueue(2);
priorityQueue.add(1);
priorityQueue.add(2);
// [1, 2]
System.out.println(priorityQueue);
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(null);
list.add(3);
// [1, 2, null, 3]
System.out.println(list);
// java.lang.NullPointerException
priorityQueue.addAll(list);
System.out.println(priorityQueue);
}
// 正常示例
@Test
void contextLoads() {
Queue priorityQueue = new PriorityQueue(2);
priorityQueue.add(1);
priorityQueue.add(2);
// [1, 2]
System.out.println(priorityQueue);
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
// [1, 2, 3]
System.out.println(list);
priorityQueue.addAll(list);
// [1, 2, 1, 2, 3]
System.out.println(priorityQueue);
}