Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节

Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节

首先我们知道用PriorityQueue这个类创建的对象是一个集合,然后调用api可以将一个个对象添加入集合,然后再通过api遍历时,插入的元素就从小到大排序输出,真的太神奇了!
下面将介绍优先队列的默认用法以及我想自己写个类,然后扔到优先队列中让它也能从小到大排序怎么做?从大到小嘞?又或者我又想用系统的类比如String,但是我想按字典序从大到小能做吗?
题外话:每插入一个就会自动排序,这么强大的功能,效率一定不高吧?但如果你学过数据结构,想一下建堆的过程,以及堆排序中添加与调整堆的过程你就会发现,堆排序与优先队列每次插入排序的功能是那么契合~
下面的讲解我尝试用一种循序渐进的方式讲述我知道的优先队列,有经验的读者可能会觉得很啰嗦,但我还是觉得这能帮助你梳理一下知识点

优先队列的默认用法—从小到大排序

我们先新建一个优先队列,然后扔四个字符进去,然后用迭代器Iterator或者for-each方式遍历打印,或者直接用println()打印,结果并非从小到大,而是(层序遍历的堆,总之不是你要的~),事实上只有通过优先队列定义的api才能按从小到大取出元素,比如remove方法

此时如果你对:

1.为什么能用for each形式可以打印集合有疑惑:这就要追根溯源到这个PriorityQueue类的来源,Java集合框架是一个大家族,它们由很多的接口定义了不同的功能,再由很多抽象类去逐步实现这些接口的功能,抽象类一代代继承,最后得到如优先队列这样的最终实现类,而for each的遍历方式是它的最上面的祖先Iterable接口中的一个方法,任何实现了Iterable接口的类都能用迭代器进行遍历
2.为什么能System.out.println(XX);直接打印一个XX对象有疑惑:事实上只有实现了toString方法的类,才能在调用这个方法的时候转化成字符串再打印
回到我们的程序

public class PriorityQueueTest {
    public static void main(String[] args) {
        //这里String类型默认实现Comparable接口的 就是按字典序排序 从小大到
        //上面这个注释你可能不太明白,看下去就会明白了~,现在无视它
        var pq = new PriorityQueue<String>();
        pq.add("B");
        pq.add("D");
        pq.add("A");
        pq.add("C");
        //通过迭代器和for each,以及println输出的顺序是(层序遍历的堆)
        System.out.println(pq);
        for (String s : pq)
            System.out.print(s);
        System.out.println();
        Iterator iter = pq.iterator();
        while (iter.hasNext())
            System.out.print(iter.next());
        System.out.println();
        //isEmpty方法是AbstractCollection抽象类中的
        while (!pq.isEmpty())
            //remove方法按照优先队列中定义的每次返回最小的元素,并删去该值
            //本例的最小是字典序最小,但是这个最小的概念是可以通过用户自己定义的
            //怎么定义下面会讲
            System.out.print(pq.remove());
        System.out.println();
        System.out.println(pq);
    }
}

输出结果

[A, C, B, D]
ACBD
ACBD
//很显然上三种打印的顺序并非我们需要的(打印的是层序的堆),没有实现从小到大排序
ABCD
[]

对String类用优先队列从大到小排序
现在需要补充一个知识点:想要往优先队列里放入一个对象,它就默认会去排序调整它在集合中的位置,与Java集合框架中的其他实现类一样,而一切涉及排序功能的实现类,我们放入集合中的元素都必须实现了Comparable接口,或者在调用构造器时提供了Comparator对象为参数,这句话接下来会用示例讲解~

先来看一下String对象的源码,它能直接放入PriorityQueue类是因为它实现了Compar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值