首先我们来看一下Queue接口:

/**
* @since 1.5
*/
public interface Queue<E> extends Collection<E> { // 添加指定元素,在添加失败时(队列满),抛出IllegalStateException
boolean add(E e); // 添加指定元素,在添加失败时(队列满),返回false
boolean offer(E e); // 删除并返回头部,当队列为空时,抛出NoSuchElementException
E remove(); // 删除并返回头部,当队列为空时,返回null
E poll(); // 获取但不删除头部,当队列为空时,抛出NoSuchElementException
E element(); // 获取但不删除头部,队列为空时,返回null
E peek(); }

javadoc中对于Queue接口的表述如下:

Queue 用来存放 优先处理元素 的集合,这种场景一般用于缓冲、并发访问。

除了继承 Collection 接口的一些方法,Queue 还添加了额外的 添加、删除、查询操作。

添加、删除、查询这些个操作都提供了两种形式,其中一种在操作失败时直接抛出异常,而另一种则返回一个特殊值----false或null;后一种是特地提供给容量受限的实现类的;

(具体哪些方法抛出异常,哪些方法返回特殊值见下图)



Queue 一般都是 FIFO 的,但是也有例外,比如优先队列 priority queue(元素顺序是根据自然排序或者自定义 comparator 排序);

再比如 LIFO 的队列(跟栈一样,后进先出)。

不论进入、出去的先后顺序是怎样的,使用 remove(),poll() 方法操作的都是 头部 的元素;

而插入的位置则不一定是在队尾了,不同的 queue 会有不同的插入逻辑。

一般情况下 Queue 的实现类不允许 null 元素,因为null被poll()/peek()方法作为一个特殊返回值,以此来表示队列为空,尽管一些实现类允许null,比如LinkedList;

从上面的描述我们可以看出,Java中的Queue与我们在数据结构中理解的队列不一样:数据结构中的队列只允许FIFO,而Java中的Queue接口表示其可以是一个队列,但是其不必须是一个队列;

接下来我们来看Deque接口:

/**
* @since 1.6
*/
public interface Deque<E> extends Queue<E> {
// 添加指定元素到队头,如果失败,将抛出IllegalStateException;
// 如果是容量受限的队列,建议使用offerFirst();
void addFirst(E e); // 添加指定元素到队尾,如果失败,将抛出IllegalStateException;
// 如果是容量受限的队列,建议使用offerLast();
// 该方法和add()相同;
void addLast(E e); // 添加指定元素到队头,如果失败,返回false;
boolean offerFirst(E e); // 添加指定元素到队尾,如果失败,返回false;
// 该方法与offer()相同;
boolean offerLast(E e); // 删除并返回头部,当队列为空时,抛出NoSuchElementException;
// 该方法与remove()相同;
E removeFirst(); // 删除并返回尾部,当队列为空时,抛出NoSuchElementException;
E removeLast(); // 删除并返回头部,当队列为空时,返回null;
// 该方法与poll()相同;
E pollFirst(); // 删除并返回尾部,当队列为空时,返回null;
E pollLast(); // 获取但不删除头部,当队列为空时,抛出NoSuchElementException;
// 该方法与element()相同;
E getFirst(); // 获取但不删除队尾,当队列为空时,抛出NoSuchElementException;
E getLast(); // 获取但不删除头部,队列为空时,返回null;
// 该方法与peek()相同;
E peekFirst(); // 获取但不删除队尾,队列为空时,返回null;
E peekLast(); boolean removeFirstOccurrence(Object o);
boolean removeLastOccurrence(Object o); // *** Queue methods ***
// 队列接口方法
boolean add(E e);
boolean offer(E e);
E remove();
E poll();
E element();
E peek(); // *** Stack methods ***
// 栈相关方法 // 将指定元素入栈;
// 该方法与addFirst()相同;
void push(E e); // 弹栈;
// 该方法与removeFirst()相同;
E pop(); // *** Collection methods ***
// Collection接口方法
boolean remove(Object o);
boolean contains(Object o);
public int size();
Iterator<E> iterator();
Iterator<E> descendingIterator(); }

javadoc中对于Deque接口的表述如下:

Deque /dek/ :双端队列 Double ended queue

大多数双端队列大小不确定,但是 Deque 支持容量受限的双端队列。

Deque 接口定义了一些从头部和尾部访问元素的方法。比如分别在头部、尾部进行插入、删除、获取元素。

每个操作都有两种方法,一种在异常情况下直接抛出异常奔溃,另一种则不会抛异常,而是返回特殊的值--false或null;后一种是特地提供给容量受限的实现类的;

Deque接口继承自Queue,除了添加了双端队列的方法外,还定义了栈操作的方法,java.util.Stack推荐使用Deque进行栈操作;

关于Queue和Deque的一些联系和区别,可以总结如下:

  1. 和Queue一样,增删改查,每个操作都有两种方法,一种在异常情况下直接抛出异常奔溃,另一种则不会抛异常,而是返回特殊的值---false或null:

  2. Deque中有些新添加的方法与Queue中的某些方法预期是相等的(同一种实现,不同的方法名):

  3. 栈相关方法也是通过Deque新添加的双端队列相关方法实现(同一种实现,不同的方法名):

接下来我们来看AbstractQueue:

/**
* @since 1.5
*/
public abstract class AbstractQueue<E> extends AbstractCollection<E> implements Queue<E> { protected AbstractQueue() {
} public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
} public E remove() {
E x = poll();
if (x != null)
return x;
else
throw new NoSuchElementException();
} public E element() {
E x = peek();
if (x != null)
return x;
else
throw new NoSuchElementException();
} public void clear() {
while (poll() != null)
;
} public boolean addAll(Collection<? extends E> c) {
// 不允许添加null
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;
} }

从源码可以看出:

  1. 该类提供Queue的骨架实现;
  2. 方法 add() ,remove(),和element()分别基于offer(),poll()和peek()实现;只是在失败时抛出异常而已,而其子类就要具体实现这些方法了;
  3. 继承该类的实现类不应该允许插入null;

Java容器解析系列(6) Queue Deque AbstractQueue 详解的更多相关文章

  1. Java容器解析系列(4) ArrayList Vector Stack 详解

    ArrayList 这里关于ArrayList本来都读了一遍源码,并且写了一些了,突然在原来的笔记里面发现了收藏的有相关博客,大致看了一下,这些就是我要写的(╹▽╹),而且估计我还写不到博主的水平,这 ...

  2. Java容器解析系列(0) 开篇

    最近刚好学习完成数据结构与算法相关内容: Data-Structures-and-Algorithm-Analysis 想结合Java中的容器类加深一下理解,因为之前对Java的容器类理解不是很深刻, ...

  3. Java容器解析系列(11) HashMap 详解

    本篇我们来介绍一个最常用的Map结构--HashMap 关于HashMap,关于其基本原理,网上对其进行讲解的博客非常多,且很多都写的比较好,所以.... 这里直接贴上地址: 关于hash算法: Ha ...

  4. Java容器解析系列(7) ArrayDeque 详解

    ArrayDeque,从名字上就可以看出来,其是通过数组实现的双端队列,我们先来看其源码: /** 有自动扩容机制; 不是线程安全的; 不允许添加null; 作为栈使用时比java.util.Stac ...

  5. Java容器解析系列(9) PrioriyQueue详解

    PriorityQueue:优先级队列; 在介绍该类之前,我们需要先了解一种数据结构--堆,在有些书上也直接称之为优先队列: 堆(Heap)是是具有下列性质的完全二叉树:每个结点的值都 >= 其 ...

  6. Java容器解析系列(1) 迭代的进化——从Enumeration到Iterator

    在Java中,对于所有的Collection,都有一个特性,可以通过迭代器来遍历和删除其中的元素,因为Collection接口继承自Iterable接口. public interface Colle ...

  7. Java容器解析系列(13) WeakHashMap详解

    关于WeakHashMap其实没有太多可说的,其与HashMap大致相同,区别就在于: 对每个key的引用方式为弱引用; 关于java4种引用方式,参考java Reference 网上很多说 弱引用 ...

  8. Java容器解析系列(10) Map AbstractMap 详解

    前面介绍了List和Queue相关源码,这篇开始,我们先来学习一种java集合中的除Collection外的另一个分支------Map,这一分支的类图结构如下: 这里为什么不先介绍Set相关:因为很 ...

  9. Java容器解析系列(2) 具体化的第一步——Collection到AbstractCollection

    在通向具体化的List,Queue之前,我们需要先了解一下Collection接口和AbstractCollection抽象类,这两个都是处于Collection顶层的存在. Collection接口 ...

随机推荐

  1. consul 集群

    主机运行 : consul agent -server -bootstrap-expect 2  -data-dir D:\consul  -node=winyh -bind=192.168.10.1 ...

  2. js不需要知道图片宽高的懒加载方法(经过实际测试,不加宽高仍然是无法正常加载的,设置height:auto,height:100%,仍然显示高度为0)

    js不需要知道图片宽高的懒加载方法 懒加载是如何实现的? - 简书https://www.jianshu.com/p/e86c61468285找到一个不需要知道图片宽高的懒加载方法了(经过实际测试,不 ...

  3. Qml文件的两种加载方式

    一种是QQmlApplicationEngine搭配Window,例如: #include <QGuiApplication> #include <QQmlApplicationEn ...

  4. U-boot2010.06移植--阶段一

    2011-02-24 23:14:57 我今天的移植将分如下3步.加上写记录文档,预计时间3小时. 一,不改变源码,完成编译. 二,修改源码,搭建一个U-boot的框架,完成编译. 三,修改源码,完成 ...

  5. 【python】python嵌套循环内层循环只执行一次

    今天写了一个两个基因集找相同的基因然后输出这么个小程序就无论如何也跑不起来,原因出在循环嵌套上,这方面之前就出过问题,后来阴差阳错的就好了我也没太注意,但是最近这个问题严重制约了工作效率,我决心找到问 ...

  6. php 固定红包 + 随机红包算法

    <?php /** * 随机红包+固定红包算法[策略模式] * copyright (c) 2016 http://blog.csdn.net/CleverCode */ //配置传输数据DTO ...

  7. Docker Compose 一键部署Nginx代理Tomcat集群

    Docker Compose 一键部署Nginx代理Tomcat集群 目录结构 [root@localhost ~]# tree compose_nginx_tomcat/ compose_nginx ...

  8. saltstack 安装

    centos 6.5 saltstack 2015.5.10 (Lithium) tips:上个版本2015.5.3或者5.5有个bug,Python调用salt的unzip模块报错: 安装 在配置了 ...

  9. pytorch中的若干问题

    下载pytorch: 度盘 https://pan.baidu.com/s/1dF6ayLr?errno=0&errmsg=Auth%20Login%20Sucess&&bdu ...

  10. CMS GC启动参数优化配置

    简介: java启动参数共分为三类: 其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容: 其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现 ...