Java 集合深入理解(9):Queue 队列
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~
今天心情不太好,来学一下 List 吧!
什么是队列
队列是数据结构中比较重要的一种类型,它支持 FIFO,尾部添加、头部删除(先进队列的元素先出队列),跟我们生活中的排队类似。
队列有两种:
- 单队列
- 循环队列
单队列就是常见的队列, 每次添加元素时,都是添加到队尾:
以数组实现的队列为例,初始时队列长度固定为 4,font 和 rear 均为 0:
每添加一个元素,rear 后移一位。当添加四个元素后, rear 到了索引为 4 的位置:
这时 a1,a2 出队,front 后移动到 2:
这时想要再添加两个元素,但 rear 后移两位后就会越界:
明明有三个空位,却只能再放入一个!这就是单队列的“假溢出”情况。
(上述参考借鉴自 http://www.nowamagic.net/librarys/veda/detail/2350)
针对这种情况,解决办法就是后面满了,就再从头开始,也就是头尾相接的循环。这就是 “循环队列” 的概念。
循环队列:
循环队列中,
rear = (rear - size) % size
接着上面的例子,当 rear 大于 队列长度时,rear = ( 5 - 5) % 5 = 0 :
这样继续添加时,还可以添加几个元素:
那如何判断队列是否装满元素了呢,单使用 front == rear 无法判断究竟是空的还是满了。
两种方法:
- 加个标志 flag ,初始为 false,添加满了置为 true;
- 不以 front = rear 为放满标志,改为 (rear - front) % size = 1。
法 2 的公式放满元素时空余了一个位置,这个公式是什么意思呢?
接着上面的情况,当 rear 从后面添加元素跑到前面 0 时,再添加一个元素 a6,rear 后移一位到 1,这时 front = 2, (1 - 2) % 5 = 1, 满足放满条件。
因此,当 rear > font 时,队列中元素个数 = rear - font;
当 rear < font 时,队列中元素分为两部分: size - font 和 rear ,也就是 rear + size - font。以上述图片为例,队列中元素个数 = 1 + 5 - 2 = 4.
接着我们介绍 Java 集合框架中的队列 Queue
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 会有不同的插入逻辑。
Thanks
https://docs.oracle.com/javase/tutorial/collections/interfaces/queue.html
https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html
Java 集合深入理解(9):Queue 队列的更多相关文章
- Java集合的Stack、Queue、Map的遍历
Java集合的Stack.Queue.Map的遍历 在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一 ...
- Java 集合深入理解(8):AbstractSequentialList
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天有点无聊,来学学 AbstractSequentialList 解解闷 吧! AbstractSequentialLi ...
- Java 集合深入理解(7):ArrayList
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情有点美丽,学学 ArrayList 放松下吧! 什么是 ArrayList ArrayList 是 Java 集合 ...
- Java 集合深入理解(4):List<E> 接口
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 蓝瘦!香菇! 连着加班几天,醉了.学学 List 放松下! 在 Java 集合深入理解:Collection 中我们熟悉了 ...
- Java 集合深入理解(10):Deque 双端队列
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 什么是 Deque Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋 ...
- Java 集合深入理解(11):LinkedList
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情鱼肚白,来学学 LinkedList 吧! 日常开发中,保存一组数据使用的最多的就是 ArrayList, 其次就 ...
- Java 集合深入理解(13):Stack 栈
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情不错,再来一篇 Stack ! 数据结构中的 栈 数据结构中,栈是一种线性数据结构,遵从 LIFO(后进先出)的操 ...
- Java 集合深入理解(15):AbstractMap
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天来了解下 AbstractMap. 什么是 AbstractMap AbstractMap 是 Map 接口的的实现类 ...
- Java 集合深入理解(14):Map 概述
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 终于把 List 常用的几种容器介绍完了,接下来开始 Map 的相关介绍. 什么是 Map Java 中的 Map 接口 ...
随机推荐
- 130. Surrounded Regions -- 被某字符包围的区域
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- 冲销交货单WS_REVERSE_GOODS_ISSUE
LOOP AT ITAB. AT END OF VBELN. PERFORM FRM_LOCK_DELIVERY(ZSDS0002) USING ITAB-VBELN. CALL FUNCTION ' ...
- 石子归并问题(nyoj737)
石子合并(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的 ...
- ASP.NET-遇到的错误汇总
错误:“未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序.” 在win7 64未上,读取Excel中的数据时报的错误, 解决方法:在生成"配置管理器中" ...
- 介绍开源的.net通信框架NetworkComms
Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 开源地址是:https://github.com/MarcFletcher/ ...
- 去除Sql Server中回车换行符
这里使用了,sql 函数.replace(string_expression , string_pattern , string_replacement), 第一个参数:要查找的字段. 第二个参数:要 ...
- [vijos P1595] 学校网络
有生以来做的第二道IOI题目居然也是96'的,又是一道比我还老的题目. 纯属复习或者说再学一遍Tarjan算法,本题的主要算法就是Tarjan+缩点,对于两个子问题的答案,根据解题:强连通缩点为拓扑图 ...
- sql遍历树
oracle有直接的sql来遍历一颗树的子节点和父节点 遍历一个节点的所有子节点(classid的值就是该节点的值) select * from organization_ a start with ...
- 记一个有想法却没能力实现的硬件产品——mp3校时闹钟
枕头旁的闹钟,我想大家都用过,很便宜.用一节干电池供电.但其最大的缺点就是不太准,不能校时. 电池啥事用光,也不知道.钟是走的很慢,没按时闹,搞的自己迟了到. 于是就有了我的漫长思考过程... 先说手 ...
- DOS下快速删除文件
Windows服务器或普通操作系统中经常会遇到很多生成的临时文件需要删除,如果需要删除的文件夹中数目很多,且文件很巨大时,如果通过鼠标选择文件夹再直接删除会响应得非常慢,特别是文件数量也巨大时,Win ...