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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/daicooper/article/details/80867875

实现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);

PriorityQueue使用

import java.util.*;
public class QueueDemo {
    public static void main(String[] args) {
        PriorityQueue<String> pq = new PriorityQueue<String>();

        // 队列中的元素按照自然顺序排序,元素加入的顺序与元素在队列中的顺序无关
        pq.add("D");
        pq.add("E");
        pq.add("F");
        pq.add("A");
        pq.add("B");
        pq.add("C");

        // 输出队列中的元素,不保证以任何特定的顺序遍历优先级队列中的元素。
        // toString方法中使用了迭代器。
        System.out.println("队列中的元素:" + pq.toString());
        System.out.println("队列中的第一个元素:" + pq.peek());
        System.out.println("移除队列中的元素:" + pq.remove());
        System.out.println("队列中的元素:" + pq.toString());
        System.out.println("移除队列中的元素:" + pq.poll());
        System.out.println("队列中的元素:" + pq.toString());
    }  
}
// 队列中的元素:[A, B, C, E, D, F]
// 队列中的第一个元素:A
// 移除队列中的元素:A
// 队列中的元素:[B, D, C, E, F]
// 移除队列中的元素:B
// 队列中的元素:[C, D, F, E]

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);

ArrayDeque的使用

import java.util.*;
public class QueueDemo {
    public static void main(String[] args) {
       ArrayDeque<String> ad = new ArrayDeque<String>();

        ad.add("D");
        ad.offerFirst("E");
        ad.addFirst("F");
        ad.offer("A");
        ad.addLast("B");
        ad.offerLast("C");

        System.out.println("队列中的元素:" + ad.toString());
        System.out.println("队列中的第一个元素:" + ad.peekFirst());
        System.out.println("移除队列中的元素:" + ad.remove());
        System.out.println("队列中的元素:" + ad.toString());
        System.out.println("移除队列中的元素:" + ad.pollLast());
        System.out.println("队列中的元素:" + ad.toString());
    }  
}
// 队列中的元素:[A, B, C, E, D, F]
// 队列中的第一个元素:A
// 移除队列中的元素:A
// 队列中的元素:[B, D, C, E, F]
// 移除队列中的元素:B
// 队列中的元素:[C, D, F, E]

猜你喜欢

转载自blog.csdn.net/daicooper/article/details/80867875