Queue 源码阅读

Queue 源码阅读

仅大致过了下,有问题的请指出,谢谢。

版本

1.8

介绍

主要接口及实现

队列接口,抽象实现,优先级队列
双端队列接口,双端队列实现
  • Queue
    • abstract class AbstractQueue<E>
    • class PriorityQueue<E> extends AbstractQueue<E>
  • Deque
    • class LinkedList<E> implements Deque<E>
    • class ArrayDeque<E> implements Deque<E>
    public interface Queue<E> extends Collection<E>
    public abstract class AbstractQueue<E> extends AbstractCollection<E>
    			implements Queue<E>
    class PriorityQueue<E> extends AbstractQueue<E>
    
    public interface Deque<E> extends Queue<E>
    class LinkedList<E> extends AbstractSequentialList<E>
        		implements List<E>, Deque<E>
    class ArrayDeque<E> extends AbstractCollection<E>
                implements Deque<E>
    

(一)LinkedList

基于链表实现的双端队列。
介绍略。主要是实现了Deque的进offer、出poll、取peek系列函数。

(二)ArrayDeque

基于数组实现的双端队列。
在这里插入图片描述
在这里插入图片描述

属性

  1. transient为了自定义序列化,减少存储损耗。
  2. head和tail保存头尾索引。
  3. 最小容量为8.
transient Object[] elements
transient int head
transient int tail
private static final int MIN_INITIAL_CAPACITY = 8

构造器

  1. 默认容量:16
  2. 指定容量:需大于MIN_INITIAL_CAPACITY =8,且保证容量为2的指数倍,保证方法calculateSize
  3. headtail取默认值,0(成员变量赋对应类型默认零值)
public ArrayDeque() {
    elements = new Object[16];
}
public ArrayDeque(int numElements) {
    allocateElements(numElements);
}

// 测试:传入9,返回16;传入17,返回32
private static int calculateSize(int numElements) {
    int initialCapacity = MIN_INITIAL_CAPACITY;
    if (numElements >= initialCapacity) {
        initialCapacity = numElements;
        initialCapacity |= (initialCapacity >>>  1);
        initialCapacity |= (initialCapacity >>>  2);
        initialCapacity |= (initialCapacity >>>  4);
        initialCapacity |= (initialCapacity >>>  8);
        initialCapacity |= (initialCapacity >>> 16);
        initialCapacity++;

        if (initialCapacity < 0)   // Too many elements, must back off
            initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
    }
    return initialCapacity;
}

默认:尾部进

public void addLast(E e) {
	if (e == null)
		throw new NullPointerException();
	elements[tail] = e;
	if ( (tail = (tail + 1) & (elements.length - 1)) == head)
		doubleCapacity();
}

扩容

扩容方法为:doubleCapacity()
前提:容量满
大致流程:
1. 保存索引:head、tail、当前容量…
2. 计算新容量:elements.length << 1
3. 防止超出类型值int范围
4. 分配内存
5. 赋值并移动:由于数组队列为循环结构,需使用两次System.arrcopy;另外,head置0,tail置原长度

private void doubleCapacity() {
	assert head == tail;
	int p = head;
	int n = elements.length;
	int r = n - p; // number of elements to the right of p
	int newCapacity = n << 1;
	if (newCapacity < 0)
		throw new IllegalStateException("Sorry, deque too big");
	Object[] a = new Object[newCapacity];
	System.arraycopy(elements, p, a, 0, r);
	System.arraycopy(elements, 0, a, r, p);
	elements = a;
	head = 0;
	tail = n;
}

默认:首部出

public E pollFirst() {
	int h = head;
	@SuppressWarnings("unchecked")
	E result = (E) elements[h];
	// Element is null if deque empty
	if (result == null)
		return null;
	elements[h] = null;     // Must null out slot
	head = (h + 1) & (elements.length - 1);
	return result;
}

容量计算

public int size() {
	return (tail - head) & (elements.length - 1);
}

空判断

public boolean isEmpty() {
	return head == tail;
}

(三)PriorityQueue

基于数组实现的优先级队列。

属性

  1. 默认容量:11
  2. 默认比较器:null
private static final int DEFAULT_INITIAL_CAPACITY = 11;
transient Object[] queue
private int size = 0
private final Comparator<? super E> comparator
transient int modCount = 0

扩容

容量小于64,容量增加一倍;容量大于等于64,容量增加50%。

private void grow(int minCapacity) {
	int oldCapacity = queue.length;
	// Double size if small; else grow by 50%
	int newCapacity = oldCapacity + ((oldCapacity < 64) ?
									 (oldCapacity + 2) :
									 (oldCapacity >> 1));
	// overflow-conscious code
	if (newCapacity - MAX_ARRAY_SIZE > 0)
		newCapacity = hugeCapacity(minCapacity);
	queue = Arrays.copyOf(queue, newCapacity);
}

默认尾部进,向上调整

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(i, e);
    return true;
}

向上调整

private void siftUpComparable(int k, E x) {
    Comparable<? super E> key = (Comparable<? super E>) x;
    while (k > 0) {
        int parent = (k - 1) >>> 1;
        Object e = queue[parent];
        if (key.compareTo((E) e) >= 0)
            break;
        queue[k] = e;
        k = parent;
    }
    queue[k] = key;
}

默认首部出,取尾部元素复制给queue[0],向下调整

public E poll() {
    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;
}

向下调整

private void siftDownComparable(int k, E x) {
    Comparable<? super E> key = (Comparable<? super E>)x;
    int half = size >>> 1;        // loop while a non-leaf
    while (k < half) {
        int child = (k << 1) + 1; // assume left child is least
        Object c = queue[child];
        int right = child + 1;
        if (right < size &&
            ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
            c = queue[child = right];
        if (key.compareTo((E) c) <= 0)
            break;
        queue[k] = c;
        k = child;
    }
    queue[k] = key;
}

内置迭代器

迭代器遍历数组,即堆按照自顶向下,自左向右的方式遍历。

发布了29 篇原创文章 · 获赞 12 · 访问量 9375

猜你喜欢

转载自blog.csdn.net/qq_31854267/article/details/103986222
今日推荐