Queue、PriorityQueue源码分析

源码分析

一、Queue接口

public interface Queue<E> extends Collection<E> {
    //队列头添加元素,若队列已满则抛出异常
    boolean add(E e);

    //队列头添加元素,若队列满时不会抛出异常而是做一些相应的处理
    boolean offer(E e);

    //队列头删除元素,若队列为空则抛出异常
    E remove();

    //队列头删除元素,若队列为空则返回NULL
    E poll();

    //返回队列头元素,若为空抛出异常
    E element();

    //返回队列头元素,若为空返回NULL
    E peek();
}

二、 PriorityQuery

①主要成员变量

    //默认初始容量11
    private static final int DEFAULT_INITIAL_CAPACITY = 11;

    //底层采用Object数组存储
    //基于二叉堆的数据结构实现优先队列
    transient Object[] queue;

    //队列中元素数量
    private int size = 0;

②构造方法

    //默认构造 初始化一个大小为11的queue,队列中元素按自然顺序排序
    public PriorityQueue() {
        this(DEFAULT_INITIAL_CAPACITY, null);
    }
    
    //也可以自定义队列大小,队列中元素自然排序
    public PriorityQueue(int initialCapacity) {
        this(initialCapacity, null);
    }

    //创建一个默认大小为11的优先队列 队列中的元素按照指定比较器进行排序
    public PriorityQueue(Comparator<? super E> comparator) {
        this(DEFAULT_INITIAL_CAPACITY, comparator);
    }

    //根据指定大小和比较器创建优先队列
    public PriorityQueue(int initialCapacity,
                         Comparator<? super E> comparator) {
        // Note: This restriction of at least one is not actually needed,
        // but continues for 1.5 compatibility
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        //这里值的一提的是,ArrayList和HashMap在初始化时都采用懒加载
        this.queue = new Object[initialCapacity];
        this.comparator = comparator;
    }

③添加元素:add()、offer()

    //底层直接调用了offer方法
    public boolean add(E e) {
        return offer(e);
    }

    
    public boolean offer(E e) {
        //检查插入元素是否为空
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        //插入前判断队列是否已满
        if (i >= queue.length)
            //满了就扩容
            grow(i + 1);
        size = i + 1;
        //若队列为空 放在队列首即可
        if (i == 0)
            queue[0] = e;
        else
            //若队列中还存在其他元素,则需要通过siftUp调整堆保持二叉堆的特性
            siftUp(i, e);
        return true;
    }

    //扩容
    private void grow(int minCapacity) {
        int oldCapacity = queue.length;
        // 若扩容前容量小于64 则扩容2倍,否则扩容1.5倍
        int newCapacity = oldCapacity + ((oldCapacity < 64) ?
                                         (oldCapacity + 2) :
                                         (oldCapacity >> 1));
        // 若扩容后超过queue最大容量,进行一些特殊处理
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        queue = Arrays.copyOf(queue, newCapacity);
    }

④删除元素remove(),poll()

    
    public E poll() {
        //若队列为空 返回null
        if (size == 0)
            return null;
        
        int s = --size;
        modCount++;
        //取出队列首元素
        E result = (E) queue[0];
        //取出队列末元素
        E x = (E) queue[s];
        //队列末删除
        queue[s] = null;
        if (s != 0)
            //自上而下堆化
            siftDown(0, x);
        return result;
    }

   
    public boolean remove(Object o) {
        //获取o的index
        int i = indexOf(o);
        if (i == -1)
            return false;
        else {
            //移除元素
            removeAt(i);
            return true;
        }
    }

    private E removeAt(int i) {
        // assert i >= 0 && i < size;
        modCount++;
        int s = --size;
        //若删除的元素index位于尾部 直接置为空即可
        if (s == i) // removed last element
            queue[i] = null;
        else {//需要进行堆化
            E moved = (E) queue[s];
            queue[s] = null;
            siftDown(i, moved);
            if (queue[i] == moved) {
                siftUp(i, moved);
                if (queue[i] != moved)
                    return moved;
            }
        }
        return null;
    }

⑤获取元素peek()

    //若队列为空返回null else 返回队列首部元素
    public E peek() {
        return (size == 0) ? null : (E) queue[0];
    }

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值