Read Queue Source
Only over roughly the next, please indicate in question, thank you.
version
1.8
Introduction
Main Interface and Implementation
队列接口,抽象实现,优先级队列
双端队列接口,双端队列实现
- Queue
- abstract class AbstractQueue<E>
- class PriorityQueue<E> extends AbstractQueue<E>
- and
- 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 based on linked list implementation.
Introduction slightly. Mainly achieved Deque into offer
, out of poll
, take the peek
family of functions.
(B) ArrayDeque
Deque Array Processor.
Attributes
transient
Custom serialization order to reduce storage losses.- head and tail head and tail save index.
- The minimum capacity of 8.
transient Object[] elements
transient int head
transient int tail
private static final int MIN_INITIAL_CAPACITY = 8
Constructor
- Default Capacity: 16
- Specify capacity: greater than required
MIN_INITIAL_CAPACITY =8
, and to ensure that the capacity of power of two times the assurance methodcalculateSize
head
Andtail
the default value, 0 (default type member corresponding to the variable a zero value)
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;
}
Enter
Default: the tail into
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
}
Expansion
Expansion method: doubleCapacity()
Prerequisite: full capacity of
the general process:
1. Save index: head, tail, the current capacity ...
2. Calculate the new capacity: elements.length << 1
3. Type Value prevent exceeding int
the range of
4 to allocate memory
5. assignment and move: Since the array queues cyclic structure, need to use twice System.arrcopy
; Further, head set to 0, tail opposite the original length
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;
}
Out
Default: a header
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;
}
Capacity calculation
public int size() {
return (tail - head) & (elements.length - 1);
}
Empty judgment
public boolean isEmpty() {
return head == tail;
}
(C) PriorityQueue
Priority queue array-based implementation.
Attributes
- Default Capacity: 11
- Default comparator: 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
Expansion
Capacity is less than 64, double the capacity; capacity not less than 64, a 50% increase in capacity.
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);
}
Enter
Into the tail default, adjusted upwards
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;
}
Upward adjustment
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;
}
Out
A default header, copy elements to take the tail queue[0]
, downward adjustment
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;
}
Downward adjustment
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;
}
Built-in iterator
Iterates over the array, i.e., in accordance with the top-down stack, traversing from left to right manner.