package java.util; import java.io.Serializable; import java.util.function.Consumer; import sun.misc.SharedSecrets; //Deque的实现类,基于数组实现双端队列 //可变数组,没有容量限制,线程不安全,不支持null值 public class ArrayDeque<E> extends AbstractCollection<E> implements Deque<E>, Cloneable, Serializable { transient Object[] elements; // 数组队列,非私有,便于内部类访问 transient int head;//队列头 transient int tail;//队列尾 private static final int MIN_INITIAL_CAPACITY = 8;//队列的最小容量 // ****** Array allocation and resizing utilities ****** private static int calculateSize(int numElements){ int initialCapacity = MIN_INITIAL_CAPACITY; //这一段代码是将从最高位1开始,将后面全部变成1,也就是找到一个刚好比initialCapacity的2^n数 if(numElements >= initialCapacity){ initialCapacity = numElements; initialCapacity |= (initialCapacity >>> 1);//>>>无符号右移,高位补0 initialCapacity |= (initialCapacity >>> 2); initialCapacity |= (initialCapacity >>> 4); initialCapacity |= (initialCapacity >>> 8); initialCapacity |= (initialCapacity >>> 16); initialCapacity++; if(initialCapacity < 0) // Too many elements, must back off,符号位为1 initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements } return initialCapacity; } //初始化队列(数组) private void allocateElements(int numElements){ elements = new Object[calculateSize(numElements)]; } //扩展队列,队列容量变为2倍。 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]; //分两次将原数据复制到数组a中 System.arraycopy(elements, p, a, 0, r); //native方法 System.arraycopy(elements, 0, a, r, p); elements = a; head = 0; tail = n; } //将数组数据从element复制到数组a private <T> T[] copyElements(T[] a){ if(head < tail){ System.arraycopy(elements, head, a, 0, size()); }else if(head > tail){ int headPortionLen = elements.length - head; System.arraycopy(elements, head, a, 0, headPortionLen); System.arraycopy(elements, 0, a, headPortionLen, tail); } return a; } //双端队列的无参构造,没有指定队列容量 public ArrayDeque(){ elements = new Object[16]; } //指定了队列容量的构造方法 public ArrayDeque(int numElements){ allocateElements(numElements); } //根据一个容器来构造双端队列,并容器所有数据添加到双端队列中 public ArrayDeque(Collection<? extends E> c){ allocateElements(c.size()); //容量是刚好比c的2^n addAll(c); } //在双端队列前面插入数据 public void addFirst(E e){ if(e == null) throw new NullPointerException(); //不能插入null elements[head = (head - 1) & (elements.length - 1)] = e;//element-1是比length小的全1的数,保证head-1不会超过length if(head == tail) doubleCapacity(); } //在双端后面插入数据 public void addLast(E e){ if(e == null) throw new NullPointerException(); elements[tail] = e; if((tail = (tail + 1) & (elements.length - 1)) == head) doubleCapacity(); } //这里的offer同add public boolean offerFirst(E e){ addFirst(e); return true; } public boolean offerLast(E e){ addLast(e); return true; } //从队列头部移除一个元素,会抛异常 public E removeFirst(){ E x = pollFirst(); if(x == null) throw new NoSuchElementException(); return x; } public E removeLast(){ E x = pollLast(); if(x == null) throw new NoSuchElementException(); return x; } 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 E pollLast(){ int t = (tail - 1) & (elements.length - 1); @SuppressWarnings("unchecked") E result = (E) elements[t]; if(result == null) return null; elements[t] = null; tail = t; return result; } public E getFirst(){ @SuppressWarnings("unchecked") E result = (E) elements[head]; if(result == null) throw new NoSuchElementException(); return result; } public E getLast(){ @SuppressWarnings("unchecked") E result = (E) elements[(tail - 1) & (elements.length - 1)]; if(result == null) throw new NoSuchElementException(); return result; } @SuppressWarnings("unchecked") public E peekFirst(){ // elements[head] is null if deque empty return (E) elements[head]; } @SuppressWarnings("unchecked") public E peekLast(){ return (E) elements[(tail - 1) & (elements.length - 1)]; } //从头到尾,移除第一个出现的对象o,如果没有此对象o,返回false public boolean removeFirstOccurrence(Object o){ if(o == null) return false; int mask = elements.length - 1; int i = head; Object x; while ((x = elements[i]) != null) { if(o.equals(x)){ delete(i); //删除队列中的这个元素 return true; } i = (i + 1) & mask; } return false; } public boolean removeLastOccurrence(Object o){ if(o == null) return false; int mask = elements.length - 1; int i = (tail - 1) & mask; Object x; while ((x = elements[i]) != null) { if(o.equals(x)){ delete(i); return true; } i = (i - 1) & mask; } return false; } // *** Queue methods *** public boolean add(E e){ addLast(e); return true; } public boolean offer(E e){ return offerLast(e); } public E remove(){ return removeFirst(); } public E poll(){ return pollFirst(); } public E element(){ return getFirst(); } public E peek(){ return peekFirst(); } // *** Stack methods *** public void push(E e){ addFirst(e); } public E pop(){ return removeFirst(); } //断言检查 private void checkInvariants(){ assert elements[tail] == null; assert head == tail ? elements[head] == null : (elements[head] != null && elements[(tail - 1) & (elements.length - 1)] != null); assert elements[(head - 1) & (elements.length - 1)] == null; } //删除队列的元素 private boolean delete(int i){ checkInvariants(); //断言 final Object[] elements = this.elements; final int mask = elements.length - 1; final int h = head; final int t = tail; final int front = (i - h) & mask; final int back = (t - i) & mask; // Invariant: head <= i < tail mod circularity if(front >= ((t - h) & mask)) //检查是否有并发操作 throw new ConcurrentModificationException(); // Optimize for least element motion if(front < back){ if(h <= i){ System.arraycopy(elements, h, elements, h + 1, front); }else{ // Wrap around System.arraycopy(elements, 0, elements, 1, i); elements[0] = elements[mask]; System.arraycopy(elements, h, elements, h + 1, mask - h); } elements[h] = null; head = (h + 1) & mask; return false; }else{ if(i < t){ // Copy the null tail as well System.arraycopy(elements, i + 1, elements, i, back); tail = t - 1; }else{ // Wrap around System.arraycopy(elements, i + 1, elements, i, mask - i); elements[mask] = elements[0]; System.arraycopy(elements, 1, elements, 0, t); tail = (t - 1) & mask; } return true; } } // *** Collection Methods *** public int size(){ return (tail - head) & (elements.length - 1); } public boolean isEmpty(){ return head == tail; } public Iterator<E> iterator(){ return new DeqIterator(); } public Iterator<E> descendingIterator(){ return new DescendingIterator(); } private class DeqIterator implements Iterator<E> { private int cursor = head; private int fence = tail; private int lastRet = -1; public boolean hasNext(){ return cursor != fence; } public E next(){ if(cursor == fence) throw new NoSuchElementException(); @SuppressWarnings("unchecked") E result = (E) elements[cursor]; // This check doesn't catch all possible comodifications, // but does catch the ones that corrupt traversal if(tail != fence || result == null) throw new ConcurrentModificationException(); lastRet = cursor; cursor = (cursor + 1) & (elements.length - 1); return result; } public void remove(){ if(lastRet < 0) throw new IllegalStateException(); if(delete(lastRet)){ // if left-shifted, undo increment in next() cursor = (cursor - 1) & (elements.length - 1); fence = tail; } lastRet = -1; } public void forEachRemaining(Consumer<? super E> action){ Objects.requireNonNull(action); Object[] a = elements; int m = a.length - 1, f = fence, i = cursor; cursor = f; while (i != f) { @SuppressWarnings("unchecked") E e = (E) a[i]; i = (i + 1) & m; if(e == null) throw new ConcurrentModificationException(); action.accept(e); } } } private class DescendingIterator implements Iterator<E> { private int cursor = tail; private int fence = head; private int lastRet = -1; public boolean hasNext(){ return cursor != fence; } public E next(){ if(cursor == fence) throw new NoSuchElementException(); cursor = (cursor - 1) & (elements.length - 1); @SuppressWarnings("unchecked") E result = (E) elements[cursor]; if(head != fence || result == null) throw new ConcurrentModificationException(); lastRet = cursor; return result; } public void remove(){ if(lastRet < 0) throw new IllegalStateException(); if(!delete(lastRet)){ cursor = (cursor + 1) & (elements.length - 1); fence = head; } lastRet = -1; } } public boolean contains(Object o){ if(o == null) return false; int mask = elements.length - 1; int i = head; Object x; while ((x = elements[i]) != null) { if(o.equals(x)) return true; i = (i + 1) & mask; } return false; } public boolean remove(Object o){ return removeFirstOccurrence(o); } public void clear(){ int h = head; int t = tail; if(h != t){ // clear all cells head = tail = 0; int i = h; int mask = elements.length - 1; do { elements[i] = null; i = (i + 1) & mask; } while (i != t); } } public Object[] toArray(){ return copyElements(new Object[size()]); } @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a){ int size = size(); if(a.length < size) a = (T[]) java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); copyElements(a); if(a.length > size) a[size] = null; return a; } // *** Object methods *** public ArrayDeque<E> clone(){ try { @SuppressWarnings("unchecked") ArrayDeque<E> result = (ArrayDeque<E>) super.clone(); result.elements = Arrays.copyOf(elements, elements.length); return result; } catch (CloneNotSupportedException e) { throw new AssertionError(); } } private static final long serialVersionUID = 2340985798034038923L; //把deque写入到流中 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ s.defaultWriteObject(); // Write out size s.writeInt(size()); // Write out elements in order. int mask = elements.length - 1; for(int i = head; i != tail; i = (i + 1) & mask){ s.writeObject(elements[i]); } } //从流中读数据到deque private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException{ s.defaultReadObject(); // Read in size and allocate array int size = s.readInt(); int capacity = calculateSize(size); SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity); allocateElements(size); head = 0; tail = size; // Read in all elements in the proper order. for(int i = 0; i < size; i++){ elements[i] = s.readObject(); } } public Spliterator<E> spliterator(){ return new DeqSpliterator<E>(this, -1, -1); } static final class DeqSpliterator<E> implements Spliterator<E> { private final ArrayDeque<E> deq; private int fence; // -1 until first use private int index; // current index, modified on traverse/split /** * Creates new spliterator covering the given array and range */ DeqSpliterator(ArrayDeque<E> deq, int origin, int fence){ this.deq = deq; this.index = origin; this.fence = fence; } private int getFence(){ // force initialization int t; if((t = fence) < 0){ t = fence = deq.tail; index = deq.head; } return t; } public DeqSpliterator<E> trySplit(){ int t = getFence(), h = index, n = deq.elements.length; if(h != t && ((h + 1) & (n - 1)) != t){ if(h > t) t += n; int m = ((h + t) >>> 1) & (n - 1); return new DeqSpliterator<>(deq, h, index = m); } return null; } public void forEachRemaining(Consumer<? super E> consumer){ if(consumer == null) throw new NullPointerException(); Object[] a = deq.elements; int m = a.length - 1, f = getFence(), i = index; index = f; while (i != f) { @SuppressWarnings("unchecked") E e = (E) a[i]; i = (i + 1) & m; if(e == null) throw new ConcurrentModificationException(); consumer.accept(e); } } public boolean tryAdvance(Consumer<? super E> consumer){ if(consumer == null) throw new NullPointerException(); Object[] a = deq.elements; int m = a.length - 1, f = getFence(), i = index; if(i != fence){ @SuppressWarnings("unchecked") E e = (E) a[i]; index = (i + 1) & m; if(e == null) throw new ConcurrentModificationException(); consumer.accept(e); return true; } return false; } public long estimateSize(){ int n = getFence() - index; if(n < 0) n += deq.elements.length; return (long) n; } @Override public int characteristics(){ return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.NONNULL | Spliterator.SUBSIZED; } } }