java集合框架--实现Queue和Deque接口类

实现Queue 和 Qeque 接口的类

描述
AbstractDueue此类提供某些 Queue 方法的骨干实现,为其它类集合的实现提供方便
PriorityQueue一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法
ArrayDeque双端队列的一个数组实现, 数组双端队列没有容量限制;它们可根据需要增加以支持使用
LinkedLis通过继承 AbstractSequentialList 来实现链接列表

LinkedList 类实现了接口 Queue 和 Deque, 具备了操作队列的基本方法。通常可以作为队列 和 双向队列的实现类使用,也是用得比较普遍的队列数据结构。

实现 Queue 和 Deque 接口的类图
这里写图片描述

PriorityQueue 类

一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。 优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象。

此队列的“头”是按指定排序方式确定的最小元素。如果多个元素都是最小值,则头是其中一个元素 ——— 选择方法是任意的。队列获取操作 poll, remove, peek 和 element 访问处于队列头的元素。

优先级队列是无界的,但是有一个内部容量, 控制着用于存储队列元素的数组大小。它通常至少等于队列的大小。随着不断向优先级队列添加元素,其容量会自动增加。无须指定容量增加策略的细节。

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。方法 iterator()中提供的迭代器不保证以任何特定的顺序遍历优先级队列中的元素。

此实现为排队和出队方法 (offer,poll, remove() 和add() 提供)O(long(n))时间,为 remove( Object) 和 contains( Object) 方法提供线性时间,为 获取方法(peek,element,和size)提供固定时间。

PriorityQueue 提供了如下 6 个构造函数。

// 使用默认的初始容量(11)创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。
public PriorityQueue();

// 使用指定的初始容量创建一个 PriorityQueue 并根据其自然顺序对元素进行排序
public PriorityQueue(int initialCapacity);

// 使用指定的初始容量创建一个 PriorityQueue ,并根据指定的比较器对元素进行排序
public PriorityQueue(int initialCapacity, Comparator<? super E> comparator);

// 创建包含指定 collection 中的元素的 PriorityQueue 。
// 如果指定的 collection 是 SortedSet 的一个实例
// 或者是另一个 PriorityQueue 那么此优先级队列将根据相同顺序进行排序。
// 否则,此优先级队列将根据元素的自然顺序进行排序。
public PriorityQueue(Collection <? extends E> c);

// 创建包含指定优先级队列元素的 PriorityQueue。 此优先级队列将根据与给定优先级队列相同的顺序进行排序。
public PriorityQueue(PriorityQueue<? extends E) c);

// 创建包含指定有序 set 元素的 PriorityQueue。此优先级队列将根据与给定有序 set 相同的顺序进行排序。
public PriorityQueue(SortedSet<? extends E> c);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

PriorityQueue使用

import java.util.*;
public class QueueDemo {
    public static void main(String[] args) {
        PriorityQueue<String> pq = new PriorityQueue<String>();
    <span class="hljs-comment">// 队列中的元素按照自然顺序排序,元素加入的顺序与元素在队列中的顺序无关</span>
    pq.add(<span class="hljs-string">"D"</span>);
    pq.add(<span class="hljs-string">"E"</span>);
    pq.add(<span class="hljs-string">"F"</span>);
    pq.add(<span class="hljs-string">"A"</span>);
    pq.add(<span class="hljs-string">"B"</span>);
    pq.add(<span class="hljs-string">"C"</span>);

    <span class="hljs-comment">// 输出队列中的元素,不保证以任何特定的顺序遍历优先级队列中的元素。</span>
    <span class="hljs-comment">// toString方法中使用了迭代器。</span>
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"队列中的元素:"</span> + pq.toString());
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"队列中的第一个元素:"</span> + pq.peek());
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"移除队列中的元素:"</span> + pq.remove());
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"队列中的元素:"</span> + pq.toString());
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"移除队列中的元素:"</span> + pq.poll());
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"队列中的元素:"</span> + pq.toString());
}  

}
// 队列中的元素:[A, B, C, E, D, F]
// 队列中的第一个元素:A
// 移除队列中的元素:A
// 队列中的元素:[B, D, C, E, F]
// 移除队列中的元素:B
// 队列中的元素:[C, D, F, E]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

ArrayDeQue 类

是 Deque 接口的大小可变数组的实现。数组双端容量没有限制;它们可根据需要增加以支持使用。它们不是现场安全的;在没有外部同步时,它们不支持多个线程的并发方法,禁止 null 元素。此类很可能在用作堆栈时快于 Stack, 在用作队列时快于 LinkendList 。

大多数 ArrayDeque 操作可以摊销固定时间运行。异常包括 remove,removeFirstOccurrence, removeLastOccurrence, Contains, iterator,.remove() 以及批量操作,它们均以线性时间允许。

此类的 iterator 方法返回的迭代器是快速失败的:如果在创建迭代器后的任意时间通过除迭代器本身的 remove 方法之外的任何其他方式修改了双端队列,则迭代器通常将抛出 ConcurrrentModificationException.因此,面对并发修改,迭代器很快就会完全失败,而不是冒着在将来不确定的时刻任意发生不确定行为的风险。

注意: 迭代器的快速失败行为不能得到保证。一般来说,存在不同步的并发修改时,不可能做出任何坚决的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException 。以此,编写依赖于此异常的程序是错误的,
正确的做法是:迭代器的快速失败行为应该仅用于检测错误(bug)。
ArrayDeque提供了如下 3 个构造函数:

//构造一个初始容量能够容纳16 个元素的空数组双端队列
public ArrayDeque();

//构造一个初始容量能够容纳指定数量的元素的空数组双端队列
public ArrayDeque(int numElements);

//构造一个包含指定 collection 的元素的双端队列,这些元素按 collection 的迭代器返回的顺序排序 (collection 迭代器返回的第一个元素将是第一个元素,或双端队列的开头)
public ArrayDeque(Collection<? extends E> c);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ArrayDeque的使用

import java.util.*;
public class QueueDemo {
    public static void main(String[] args) {
       ArrayDeque<String> ad = new ArrayDeque<String>();
    ad<span class="hljs-preprocessor">.add</span>(<span class="hljs-string">"D"</span>)<span class="hljs-comment">;</span>
    ad<span class="hljs-preprocessor">.offerFirst</span>(<span class="hljs-string">"E"</span>)<span class="hljs-comment">;</span>
    ad<span class="hljs-preprocessor">.addFirst</span>(<span class="hljs-string">"F"</span>)<span class="hljs-comment">;</span>
    ad<span class="hljs-preprocessor">.offer</span>(<span class="hljs-string">"A"</span>)<span class="hljs-comment">;</span>
    ad<span class="hljs-preprocessor">.addLast</span>(<span class="hljs-string">"B"</span>)<span class="hljs-comment">;</span>
    ad<span class="hljs-preprocessor">.offerLast</span>(<span class="hljs-string">"C"</span>)<span class="hljs-comment">;</span>

    System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"队列中的元素:"</span> + ad<span class="hljs-preprocessor">.toString</span>())<span class="hljs-comment">;</span>
    System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"队列中的第一个元素:"</span> + ad<span class="hljs-preprocessor">.peekFirst</span>())<span class="hljs-comment">;</span>
    System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"移除队列中的元素:"</span> + ad<span class="hljs-preprocessor">.remove</span>())<span class="hljs-comment">;</span>
    System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"队列中的元素:"</span> + ad<span class="hljs-preprocessor">.toString</span>())<span class="hljs-comment">;</span>
    System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"移除队列中的元素:"</span> + ad<span class="hljs-preprocessor">.pollLast</span>())<span class="hljs-comment">;</span>
    System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"队列中的元素:"</span> + ad<span class="hljs-preprocessor">.toString</span>())<span class="hljs-comment">;</span>
}  

}
// 队列中的元素:[A, B, C, E, D, F]
// 队列中的第一个元素:A
// 移除队列中的元素:A
// 队列中的元素:[B, D, C, E, F]
// 移除队列中的元素:B
// 队列中的元素:[C, D, F, E]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java中的DequeQueue都是集合框架中的接口,但它们有一些区别。 Queue是一个先进先出(FIFO)的数据结构,它只允许在队列的一端插入元素,在另一端删除元素。Queue接口有许多实现,如LinkedList、PriorityQueue等。 而Deque(Double Ended Queue)是一个双端队列,它允许在队列的两端插入和删除元素。Deque接口也有许多实现,如ArrayDeque、LinkedList等。 因此,DequeQueue更加灵活,可以在队列的两端进行插入和删除操作。而Queue只能在队列的一端进行插入和删除操作。 ### 回答2: Deque(双端队列)和Queue(队列)是Java中两种不同的数据结构。 首先,Queue是一种先进先出(FIFO)的数据结构。它只能在队列的一端(称为队尾)插入新元素,并从另一端(称为队首)删除元素。Queue的常用实现类有LinkedList和PriorityQueue。 而Deque是一种既可以在队尾插入新元素,也可以在队首删除元素的数据结构。它支持FIFO和LIFO(后进先出)两种操作。在Java中,DequeQueue的子接口。Deque的常用实现类有LinkedList和ArrayDeque。 最明显的区别是,Queue只能在队尾插入元素和在队首删除元素。而Deque除了支持这两种操作外,还可以在队尾删除元素和在队首插入元素。这使得Deque相比于Queue在操作灵活性上更加强大。 此外,由于Deque实现Queue接口,所以可以在需要Queue的地方使用Deque。也就是说,Deque既可以作为队列使用,也可以作为栈使用(栈是LIFO结构)。 在性能上,由于Deque实现类LinkedList和ArrayDeque都是使用了双向链表和动态数组,因此它们在插入和删除操作上的性能较好,而LinkedList对于随机访问(根据索引获取元素)的性能较差。 总结来说,Deque相比于Queue更加灵活,既可以作为队列使用,也可以作为栈使用。它允许在队尾和队首进行插入和删除操作,可满足更多的应用需求。而Queue只支持队尾插入和队首删除操作,适用于先进先出的场景。 ### 回答3: Java中的DequeQueue都是用来存储元素的数据结构,但它们有一些区别。 首先,Queue是一个接口,它表示一个具有FIFO(先进先出)特性的数据结构。常见的实现类有LinkedList和PriorityQueue。它提供了一些基本的操作方法,例如插入、删除、查询队列头部元素等。 而Deque(Double Ended Queue)也是一个接口,它继承了Queue接口,并且允许在两端进行插入、删除和查询操作。除了拥有Queue接口的特性外,Deque还提供了一些额外的方法,例如在队列的头部和尾部插入和删除元素,以及获取头部和尾部元素。常见的实现类有LinkedList和ArrayDeque。 因此,主要区别在于Deque是一个双端队列,可以在队列的头部和尾部进行插入、删除和查询操作,而Queue只能在队列的尾部进行插入操作,头部进行删除和查询操作。 另外,Queue接口还提供了一些用于处理特定需求的实现类,例如PriorityQueue可以根据元素的优先级进行排序,ArrayBlockingQueue可以限制队列的容量等。 综上所述,Queue只能在队列尾部进行插入操作,具有FIFO特性;而Deque是一个双端队列,可以在队列的头部和尾部进行插入、删除和查询操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值