1.什么是队列?
队列是数据结构中比较重要的一种类型(是一种数据结构),它支持 FIFO,尾部添加、头部删除(先进队列的元素先出队列),跟我们生活中的排队类似。
2.什么情况下使用队列?
一般情况下,如果是对一些及时消息的处理,并且处理时间很短的情况下是不需要队列的,直接阻塞式的方法调用就可以了。但是如果在消息处理的时候特别费时间,这个时候如果有新消息来了,就只能处于阻塞状态,造成用户等待。这个时候便需要引入队列了。当接收到消息后,先把消息房贷队列中,然后再用行的线程进行处理,这个时候就不会有消息阻塞了。
3.队列介绍:
队列有两种:① 单队列 : 就是常见的队列,每次添加元素时,都是添加对队尾。
② 循环队列(暂不介绍)
4.队列Queue
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞
Java 集合中的 Queue 继承自 Collection 接口 ,Deque, LinkedList, PriorityQueue, BlockingQueue 等类都实现了它。
Queue 用来存放 等待处理元素 的集合,这种场景一般用于缓冲、并发访问。
除了继承 Collection 接口的一些方法,Queue 还添加了额外的 添加、删除、查询操作。
添加、删除、查询这些个操作都提供了两种形式,其中一种在操作失败时直接抛出异常,而另一种则返回一个特殊的值:
Queue 方法介绍:
1.add(E), offer(E) 在尾部添加:
boolean add(E e);
boolean offer(E e);
他们的共同之处是建议实现类禁止添加 null 元素,否则会报空指针 NullPointerException;
不同之处在于 add() 方法在添加失败(比如队列已满)时会报 一些运行时错误 错;而 offer() 方法即使在添加失败时也不会奔溃,只会返回 false。
2016.11.21 添加
注意
Queue 是个接口,它提供的 add, offer 方法初衷是希望子类能够禁止添加元素为 null,这样可以避免在查询时返回 null 究竟是正确还是错误。
事实上大多数 Queue 的实现类的确响应了 Queue 接口的规定,比如 ArrayBlockingQueue,PriorityBlockingQueue 等等。
但还是有一些实现类没有这样要求,比如 LinkedList。
感谢 sumsear 指出。
2.remove(), poll() 删除并返回头部:
E remove();
E poll();
当队列为空时 remove() 方法会报 NoSuchElementException 错; 而 poll() 不会奔溃,只会返回 null。
3.element(), peek() 获取但不删除:
E element();
E peek();
当队列为空时 element() 抛出异常;peek() 不会奔溃,只会返回 null。
其他
1.虽然 LinkedList 没有禁止添加 null,但是一般情况下 Queue 的实现类都不允许添加 null 元素,为啥呢?因为 poll(), peek() 方法在异常的时候会返回 null,你添加了 null 以后,当获取时不好分辨究竟是否正确返回。
2.Queue 一般都是 FIFO 的,但是也有例外,比如优先队列 priority queue(它的顺序是根据自然排序或者自定义 comparator 的);再比如 LIFO 的队列(跟栈一样,后来进去的先出去)。
不论进入、出去的先后顺序是怎样的,使用 remove(),poll() 方法操作的都是 头部 的元素;而插入的位置则不一定是在队尾了,不同的 queue 会有不同的插入逻辑。
5.代码示例:
import java.util.LinkedList;
import java.util.Queue;
import org.junit.Before;
import org.junit.Test;
/**
队列测试:实现类使用LinkedList
Queue也有很多其他的实现类,比如java.util.concurrent.LinkedBlockingQueue。
-
LinkedBlockingQueue是一个阻塞的线程安全的队列,底层实现也是使用链式结构。
*/
public class TestQuene {// 定义一个队列
Queue<String> queue;@Before
public void before() {
// 实例化队列变量
queue = new LinkedList<String>();// add方法向队列中添加元素,返回布尔值,add方法添加失败时会抛异常,不推荐使用 // queue.add("1"); // queue.add("2"); // queue.add("3"); // queue.add("4"); // queue.add("5"); // offer方法向队列中添加元素,返回布尔值 queue.offer("a"); queue.offer("b"); queue.offer("c"); queue.offer("d"); queue.offer("e");
}
// poll方法移除队列首个元素并返回,若队列为空,返回null
@Test
public void test1() {
// 弹出元素
String pollEle = queue.poll(); // 先进先出,弹出了a
System.out.println(pollEle); // a
System.out.println(queue); // [b, c, d, e]
}// remove方法移除首个元素并返回,若队列为空,会抛出异常:NoSuchElementException,不推荐使用
@Test
public void test2() {
// 弹出元素
String remove = queue.remove(); // 先进先出,弹出了a
System.out.println(remove); // a
System.out.println(queue); // [b, c, d, e]
}// peek方法返回队列首个元素,但不移除,若队列为空,返回null
@Test
public void test3() {
// 查看首个元素
String peek = queue.peek(); // 首个元素是a,最先加入
System.out.println(peek); // a
System.out.println(queue); // [a, b, c, d, e]
}// element方法返回队列的头元素,但不移除,若队列为空,会抛出异常:NoSuchElementException,不推荐使用
@Test
public void test4() {
// 查看首个元素
String element = queue.element();
System.out.println(element); // a
System.out.println(queue); // [a, b, c, d, e]
}
}
-->队列的结合使用