[数据结构与算法]:队列

说明

为了加深自己对队列的理解,现在总结一下队列的一些知识点。

什么是队列?

队列是一种特殊的线性表,底层是由数组和链表作为架构的只暴露头和尾部操作的数据结构。
队列最重要的特性是:先进先出。这个特性可以区别于其他的数据结构。其类似于排序,原理如下图所示。请添加图片描述

Java中队列的分类

从Java继承和实现的角度来看,队列并不是一种新的东西,队列Queue和Set和List三者都继承了Collection集合,所以从本质上看它还是一个集合。
在队列镞中,队列可以分为非阻塞队列AbstractQueue(普通队列),阻塞队列(BlockingQueue)和双端队列(DqQueue)这三种。
在这里插入图片描述

Queue队列接口

Queue是java中实现队列的接口,它总共只有6个方法,如下:
Queue的6个方法分类:
压入元素(添加):add()、offer()
相同:未超出容量,从队尾压入元素,返回压入的那个元素。
区别:在超出容量时,add()方法会对抛出异常,offer()返回false

弹出元素(删除):remove()、poll()
相同:容量大于0的时候,删除并返回队头被删除的那个元素。
区别:在容量为0的时候,remove()会抛出异常,poll()返回false

获取队头元素(不删除):element()、peek()
相同:容量大于0的时候,都返回队头元素。但是不删除。
区别:容量为0的时候,element()会抛出异常,peek()返回null。

总结:add()、remove()、element()会抛出遗产,而offer() 、poll()、 peek()会返回特殊值。

阻塞队列BlockingQueue

什么是阻塞队列?
阻塞队列是一个支持两种附加操作的队列,当队列为满时,存储元素的线程会等待队列可用,当队列为空时,获取元素的线程会等待队列为非空。
在这里插入图片描述
阻塞队列的四组API
1、抛出异常
2、不会抛出异常
3、阻塞等待
4、超时等待

在这里插入图片描述
其中超时等待:
如果我们要加入一个元素D,但是队列的元素满了,那么我就给它指定的时间等待,如果该等待时间过后还是满的,那么我就超时退出了。

阻塞队列中还有一个同步队列SynchronousQueue:
同步队列的特点:
1、同步队列没有容量。
2、同步队列进去一个元素,必须等待其出来之后,才能再往里面放一个元素。
3、对应的方法操作为:put和take。
同步队列SynchronousQueue和其他的阻塞队列BlockingQueue不一样,SynchronousQueue不存储元素。
put了一个元素,必须从里面先take取出来,否则不能在put进去值!

那么什么情况下我们会使用的阻塞队列?
1、多线程的并发处理
2、线程池

双端队列DoubleEndedQueue

什么是双端队列?
双端队列顾名思义就是队列的两个端口都能进出。
在这里插入图片描述

Deque有三种用途:

普通队列(一端进另一端出):
Queue queue = new LinkedList();
Deque deque = new LinkedList() ;
双端队列(两端都可进出):
Deque deque = new LinkedList() ;
堆栈:
Deque deque = new LinkedList();

Deque接口扩展(继承)了 Queue 接口。在将双端队列用作队列时,将得到 FIFO(先进先出)行为。将元素添加到双端队列的末尾,从双端队列的开头移除元素。从 Queue 接口继承的方法完全等效于 Deque 方法,如下表所示:
在这里插入图片描述
双端队列也可用作 LIFO(后进先出)堆栈。应优先使用此接口而不是遗留 Stack 类。在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。堆栈方法完全等效于 Deque 方法,如下表所示:
在这里插入图片描述
双端队列引用博客:https://blog.csdn.net/devnn/article/details/82716447

非阻塞队列

什么是非阻塞队列?
非阻塞队列不能阻塞,个人理解为普通队列,在多线程中,当队列满或空时,只能使用wait()和notify()进行队列消息传送。

Java中的非阻塞队列实现:
AbstractQueue是非阻塞队列的接口,常见的非阻塞实现类有:
1、LinkedList
2、PriorityQueue
3、ConcurrentLinkedQueue

(1)LinkedList 既实现了AbstractQueue接口也实现了Deque接口,也可作为双端队列使用。
(2)PriorityQueue 该类维护了一个有序队列,默认队头是规则排序中最小的元素,若多个最小值,则随机挑选。
排序的规则是通过构造函数comparator来实现,因此,该队列不允许插入null值或不可比较的对象。
(3)ConcurrentLinkedQueue 该类是基于链接点的线程安全队列,并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大小,ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。此队列不允许使用null元素

对Java中非阻塞队列的操作方法:
1、add(E e):将元素 e 插入到队列末尾,如果插入成功,则返回 true;如果插入失败(即队列已满),则会抛出异常;
2、remove():移除队首元素,若移除成功,则返回 true;如果移除失败(队列为空),则会抛出异常;
3、remove(Object o):移除指定的元素,若移除成功,则返回 true;如果移除失败(队列为空),则会抛出异常
4、 offer(E e):将元素 e 插入到队列末尾,如果插入成功,则返回 true;如果插入失败(即队列已满),则返回 false;
5、 poll():移除并获取队首元素,若成功,则返回队首元素;否则返回 null;
6、 peek():获取队首元素,若成功,则返回队首元素;否则返回 null
7、 isEmpty():队列是否为空
8、 size():队列长度

值得注意的是,一般情况下建议使用 offer、poll 和 peek 三个方法,不建议使用 add 和 remove 方法。因为使用 offer、poll 和 peek 三个方法可以通过返回值判断操作成功与否,而使用 add 和 remove 方法却不能达到这样的效果。
尤其对于插入操作,往往使用返回特殊值的方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值