【Java集合框架】09 ——PriorityQueue 类

一、PriorityQueue 类介绍

PriorityQueue也是集合框架中定义的类,它为我们提供了一种基于优先级处理对象的方法。
前面已经描述了对象的插入和删除在Java队列中遵循FIFO模式。然而,有时需要根据优先级处理队列的元素,这就是PriorityQueue发挥作用的地方。

PriorityQueue基于优先级堆。优先级队列的元素按照自然顺序排序,或者由队列构造时提供的Comparator排序,这取决于使用的是哪个构造函数。

1.1 PriorityQueue 层次结构

在这里插入图片描述

1.2 PriorityQueue类声明

让我们看看java.util.PriorityQueue类的声明。

public class PriorityQueue<E> extends AbstractQueue<E> implements Serializable  

1.3 PriorityQueue 的特性

优先级队列的几个重要点如下:

  • PriorityQueue不允许为空
  • 我们不能创建一个不可比较的对象的优先级队列
  • PriorityQueue是未绑定队列
  • 这个队列的头是相对于指定顺序最小的元素。如果多个元素为最小值绑定,则头部是这些元素中的一个——绑定被任意打破。
  • 由于PriorityQueue不是线程安全的,java提供了PriorityBlockingQueue类,它实现了在java多线程环境中使用的BlockingQueue接口。
  • 队列检索操作轮询、删除、查看和元素访问队列头部的元素。
  • 它为添加和轮询方法提供O(log(n))时间。
  • 它从AbstractQueue、AbstractCollection、Collection和Object类继承方法。

1.3 PriorityQueue 的 构造器

  • PriorityQueue():创建一个具有默认初始容量(11)的PriorityQueue,它根据元素的自然顺序对其进行排序。
    private static final int DEFAULT_INITIAL_CAPACITY = 11;
    /**
     * 使用默认初始值创建一个初始容量:11
     */
    public PriorityQueue() {
        this(DEFAULT_INITIAL_CAPACITY, null);
    }
  • PriorityQueue(Collection<E> c):创建一个包含指定集合中的元素的PriorityQueue。
PriorityQueue<E> pq = new PriorityQueue<E>(Collection<E> c);
  • PriorityQueue(int initialCapacity):创建一个具有指定初始容量的PriorityQueue,根据元素的自然顺序对其进行排序。
PriorityQueue<E> pq = new PriorityQueue<E>(int initialCapacity);
  • PriorityQueue(int initialCapacity, Comparator Comparator):创建一个具有指定初始容量的PriorityQueue,根据指定的比较器对其元素进行排序。
PriorityQueue<E> pq = new PriorityQueue(int initialCapacity, Comparator<E> comparator);
  • PriorityQueue(PriorityQueue c):创建一个包含指定优先级队列中的元素的PriorityQueue。
PriorityQueue<E> pq = new PriorityQueue(PriorityQueue<E> c);
  • PriorityQueue(SortedSet c):创建一个包含指定排序集中的元素的PriorityQueue。
PriorityQueue<E> pq = new PriorityQueue<E>(SortedSet<E> c);

1.3 PriorityQueue 的 基本操作

例子:下面的示例解释了优先级队列的以下基本操作。

  • boolean add(E元素):该方法将指定的元素插入到优先级队列中。
  • public peek():这个方法检索队列的头部,但不删除,如果队列为空则返回null。
  • public poll():该方法检索并删除该队列的头部,如果该队列为空,则返回null。
        // 创建优先队列
        PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();

        // 添加元素
        pQueue.add(10);
        pQueue.add(20);
        pQueue.add(15);

        System.out.println("初始优先队列:"+pQueue);

        // 检索队列的头部,但不删除
        System.out.println(pQueue.peek());

        // 检索队列的头部,并删除
        System.out.println(pQueue.poll());

        // 打印头部元素
        System.out.println(pQueue.peek());

        System.out.println("最终优先队列:"+pQueue);

输出

初始优先队列:[10, 20, 15]
10
10
15
最终优先队列:[15, 20]

二、PriorityQueue 的操作

让我们看看如何在Priority Queue类上执行一些常用操作。

2.1 添加操作

为了在优先队列中添加元素,可以使用add()方法。插入顺序不保留在PriorityQueue中。元素按照优先级顺序存储,默认情况下优先级为升序。

        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for(int i=0;i<3;i++){
            pq.add(i);
            pq.add(1);
        }
        System.out.println(pq);

输出

[0, 1, 1, 1, 2, 1]

我们不会通过打印PriorityQueue来获得已排序的元素。

2.2 删除操作

为了从优先队列中删除一个元素,可以使用remove()方法。
如果有多个这样的对象,则删除第一个出现的对象。除此之外,poll()方法还用于删除头部并返回它。

      Queue<String> pq = new PriorityQueue<>();

        pq.add("广州");
        pq.add("深圳");
        pq.add("北京");

        System.out.println("初始 队列 " + pq);

        pq.remove("深圳");

        System.out.println("删除后 " + pq);

        System.out.println("删除头队列:" + pq.poll());

        System.out.println("最终队列 " + pq);

初始 队列 [北京, 深圳, 广州]
删除后 [北京, 广州]
删除头队列:北京
最终队列 [广州]

2.3 访问操作

由于Queue遵循先进先出原则,我们只能访问队列的头部。
要访问优先级队列中的元素,可以使用peek()方法。

        PriorityQueue<String> pq = new PriorityQueue<>();
        pq.add("广州");
        pq.add("深圳");
        pq.add("东莞");
        System.out.println("PriorityQueue: " + pq);

        // 使用peek方法,访问头部
        String element = pq.peek();
        System.out.println("访问元素: " + element);

输出

PriorityQueue: [东莞, 深圳, 广州]
访问元素: 东莞

2.4 迭代操作

有多种方法可以遍历PriorityQueue。最著名的方法是将队列转换为数组并使用for循环遍历
但是,队列还有一个内置迭代器,可用于遍历队列。

 		PriorityQueue<String> pq = new PriorityQueue<>();
        pq.add("广州");
        pq.add("深圳");
        pq.add("东莞");
        System.out.println("PriorityQueue: " + pq);

        // 转换为数组 遍历
        for (Object o : pq.toArray()) {
            System.out.println(o);
        }
        
        // 内置迭代器
        Iterator iterator = pq.iterator();

        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }

输出

PriorityQueue: [东莞, 深圳, 广州]
东莞
深圳
广州
东莞 深圳 广州 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值