java8 PriorityQueue接口实现源码解析

一、类继承关系

二、使用说明

       PriorityQueue表示一个自动扩容的优先级队列,内部实现是基于数组的二叉堆,数组的第一个元素为队列中最小的元素,也是二叉堆的根节点,每次执行poll(),remove(),peek(),element()方法时都是操作队列的head元素。通过循环调用poll()方法直到返回null可保证按照排序好的顺序遍历,但是通过iterator()返回的迭代器遍历时遍历元素的顺序不是任何特定的顺序。PriorityQueue跟SortedMap一致,要求插入的元素不能为null,必须实现Comparable接口或者可以被构造时传入的Compartor实例比较,否则报错ClassCastException。PriorityQueue无容量限制,内部会根据需要自动扩容;非同步,如果要求线程安全,推荐使用PriorityBlockingQueue。测试用例如下:

public class User {
    private String userName;

    private Integer age;

    public User() {
    }

    public User(String userName, Integer age) {
        this.userName = userName;
        this.age = age;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
}


   @Test
    public void test() throws Exception {
        Queue<String> test=new PriorityQueue<>();
        test.add("test2");
        test.add("test3");
        test.add("test5");
        test.add("test4");
        test.add("test");
        test.add("test6");
        int size=test.size();
        System.out.println(size);
        System.out.println("=========iterator========");
        for(String s:test){
            System.out.println(s);//不是按照排序或者插入的顺序来的,而是数组实际保存元素的顺序
        }
        System.out.println("=========poll========");
        for(int i=0;i<size;i++){
            System.out.println(i+":"+test.poll());//按照升序的顺序遍历的,每次获取的都是当前队列的最小值
        }
    }

    @Test
    public void test2() throws Exception {
        //通过传递特定Comparator实现倒序排序
        Queue<User> queue=new PriorityQueue<>(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o2.getAge()-o1.getAge();
            }
        });
        queue.add(new User("shl",12));
        queue.add(new User("shl2",14));
        queue.add(new User("shl3",10));
        queue.add(new User("shl4",15));
        queue.add(new User("shl5",9));
        queue.add(new User("shl6",16));
        int size=queue.size();
        for(int i=0;i<size;i++){
            System.out.println(queue.poll());
        }

    }

三、二叉堆说明

      二叉堆是堆的一种,使用完全二叉树来实现。所谓完全二叉树,即高度为n的二叉树,其前n-1层必须被填满,第n层也要从左到右顺序填满。在二叉堆中,所有父节点的值均不大于(或不小于)其左右子节点的值,但对左右节点值的大小关系不做限制。若所有父节点值均不大于其左右子结点的值,这样的二叉堆叫做小根堆,小根堆根结点的值是该堆中所有结点的最小值;同样的,当所有父节点的值都不小于其左右孩子的值时,这样的对叫做大根堆,大根堆根结点的值为该堆所有结点的最大值,可以利用此特点快速找出最大值或者最小值,进而实现排序。因为二叉堆是一棵完全二叉树,不需要红黑树那样通过父节点保存对左

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值