java集合——队列和双端队列+优先级队列

感谢有奉献精神的人

转自:http://blog.youkuaiyun.com/pacosonswjtu/article/details/50323717

【0】README

0.1) 本文描述转自 core Java volume 1, 源代码为原创,旨在理解 Java集合——队列和双端队列+优先级队列 的相关知识; 
0.2) for full source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/DequeTest.java + https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/PriorityQueueTest.java


【1】双端队列:可以让人们有效地在头部和尾部同时添加和删除元素。

1.0) Deque API are as follows :

  • java.util.Interface Deque 
    Type Parameters: 
    E - the type of elements held in this collection
  • All Superinterfaces: 
    Collection, Iterable, Queue
  • All Known Subinterfaces: 
    BlockingDeque
  • All Known Implementing Classes: 
    ArrayDeque, ConcurrentLinkedDeque, LinkedBlockingDeque, LinkedList

1.1)在java SE6中, 引入了 Deque接口, 并由 ArrayDeque 和 LinkedList 类实现。 这两个类提供了双端队列, 而且在必要的时候增加队列长度;

  • API java.util.Queue 5.0 
    boolean add(E element) 
    boolean offer(E element) 
    如果队列没有满, 将给定 的元素添加到这个双端队列的尾部并返回 true。 如果队列满了,第一个方法将抛出一个 IllegalStateException, 而第二个方法返回 false;

  • E remove() + E poll() 
    假如队列不为空, 删除并返回这个队列头部的元素。如果队列为空,第一个方法抛出 NoSuchElementException, 而第二个方法返回 null;

  • E element() + E peek() 
    如果队列不为空, 返回这个队列头部的元素, 但不删除。如果队里为空, 第一个方法将抛出一个 NoSuchElementException , 而第二个方法返回 null; 
    (注意到, 以上方法中的第一个方法总是抛出异常, 而第二个方法返回null 或者 false)

  • API java.util.Deque 6 
    void addFirst(E e) 
    void addLast(E e) 
    //以上两个方法出错,抛异常; 
    boolean offerFirst(E e) 
    boolean offerLast(E e) 
    //以上两个方法出错,return false; 
    将给定的对象添加到 双端队列的头部和尾部。 如果队列满了, 前两个方法将抛出一个 IllegalStateException, 而后面两个方法返回 false;

  • E removeFirst() 
    E removeLast() 
    //以上两个方法出错,抛异常; 
    E pollFirst() 
    E pollLast() 
    //以上两个方法出错,return null; 
    如果队列不为空, 删除并返回队列头部的元素;如果队列为空, 前面两个方法将抛出一个 NoSuchElementException, 而后面两个方法返回 null;

  • E getFirst() 
    E getLast() 
    //以上两个方法出错,抛异常; 
    E peekFirst() 
    E peekLast() 
    //以上两个方法出错,return null; 
    如果队列不为空, 返回队列头部的元素但不删除;如果队列为空, 前面两个方法将抛出一个 NoSuchElementException, 而后面两个方法返回 null;

  • API java.util.ArrayDeque 6 
    ArrayDeque() 
    ArrayDeque(int intialCapacity) 
    用初始容量16或给定的初始容量构造一个无限双端队列; 
    这里写图片描述


【2】优先级队列

  • java.util.Class PriorityQueue
  • java.lang.Object
  • java.util.AbstractCollection 
    • java.util.AbstractQueue 
      • java.util.PriorityQueue
  • Type Parameters: 
    E - the type of elements held in this collection
  • All Implemented Interfaces: 
    Serializable, Iterable, Collection, Queue

2.1)优先级队列中的元素可以按照任意顺序插入, 却总是按照排序的顺序检索;也就是说, 无论何时调用 remove方法, 总会获得当前优先队列中最小的元素;

  • 2.1.1)优先队列使用了一个高效的数据结构——堆。(详见数据结构 的堆,大根堆和小根堆)
  • 2.1.2)和TreeSet一样, 一个优先队列既可以保存实现了 Comparable接口的类对象, 也可以保存在构造器中提供比较器的对象;
  • 2.1.3)优先级队列的典型应用是任务调度。 每一个任务有一个优先级, 任务以随机顺序添加到队列中。 每当启动一个新的任务时, 都将优先级最高 的任务从队列中删除;

2.2)看个荔枝: 
这里写图片描述 
这里写图片描述

API java.util.PriorityQueue 5.0
PriorityQueue()
PriorityQueue(int initialCapacity)
PriorityQueue(int initialCapacity, Comparator<? super E> c)
构造一个优先队列, 并用指定 的比较器对元素进行排序;

### Java 中 Queue Deque 的概念及用法 #### 一、Queue Deque 的定义 在 Java 集合框架中,`Queue` 是一种用于存储元素的集合接口,主要用于实现队列这种先进先出(FIFO, First-In-First-Out)的数据结构。而 `Deque` 则是一种更灵活的双端队列接口,允许从两端进行插入移除操作[^1]。 #### 二、主要功能对比 `Queue` 主要支持 FIFO 操作模式,提供了一些基本方法如 `add(E e)` 添加元素到队尾,`remove()` 移除并返回队首元素等。相比之下,`Deque` 不仅可以作为普通的队列使用,还可以充当栈或者双向队列的角色,提供了更多灵活性的方法比如 `offerFirst(E e)` 将指定元素插入此 deque 所表示的队列的开头,以及 `pollLast()` 获取并移除此 deque 的最后一个元素[^2]。 #### 三、典型实现类比较 对于 `Queue` 接口来说,常见的实现有 `LinkedList` `PriorityQueue`;而对于 `Deque` 接口,则通常由 `ArrayDeque` 来实现。尽管两者都可以用来创建队列对象,但在性能表现上存在差异——例如,在频繁执行入队/出队操作时,`ArrayDeque` 往往优于 `LinkedList` 因为其内部采用数组而非链表形式管理数据项[^4]。 #### 四、线程安全性考量 无论是基于 `Queue` 还是 `Deque` 构建的应用程序都需要考虑多线程环境下的同步问题。如果需要在线程间共享这些容器,则应选用具备线程安全特性的版本,像 `ConcurrentLinkedQueue` 对于无界非阻塞并发队列是一个不错的选择,而当涉及到带容量限制且需等待条件满足才能继续处理的情况时可考虑使用 `BlockingDeque` 及其实现类如 `LinkedBlockingDeque`[^3]。 #### 五、适用场景举例说明 - **优先级调度**: 如果应用程序中有任务按照一定顺序被执行的需求(比如高优先生效),那么应该选择实现了 `Queue` 接口但具有特殊行为模型的子类型之一 —— `PriorityQueue`。 - **缓存机制构建**: 当设计 LRU (Least Recently Used) 缓存策略时,由于经常涉及快速定位最近最少使用的条目以便淘汰之故,此时利用能够高效完成头尾增删动作的 `Deque` 实现会更加合适一些。 ```java // 使用 ArrayDeque 创建一个简单的双端队列示例 import java.util.ArrayDeque; public class Main { public static void main(String[] args){ ArrayDeque<Integer> deque = new ArrayDeque<>(); // 向头部添加元素 deque.offerFirst(1); deque.push(0); System.out.println(deque.poll()); // 输出最前面的元素并删除它 while(!deque.isEmpty()){ System.out.print(deque.pop()+" "); // 自动弹出顶部元素直到为空 } } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值