Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package java.util;
     27 
     28 import java.util.function.Consumer;
     29 
     30 /**
     31  * An unbounded priority {@linkplain Queue queue} based on a priority heap.
     32  * The elements of the priority queue are ordered according to their
     33  * {@linkplain Comparable natural ordering}, or by a {@link Comparator}
     34  * provided at queue construction time, depending on which constructor is
     35  * used.  A priority queue does not permit {@code null} elements.
     36  * A priority queue relying on natural ordering also does not permit
     37  * insertion of non-comparable objects (doing so may result in
     38  * {@code ClassCastException}).
     39  *
     40  * <p>The <em>head</em> of this queue is the <em>least</em> element
     41  * with respect to the specified ordering.  If multiple elements are
     42  * tied for least value, the head is one of those elements -- ties are
     43  * broken arbitrarily.  The queue retrieval operations {@code poll},
     44  * {@code remove}, {@code peek}, and {@code element} access the
     45  * element at the head of the queue.
     46  *
     47  * <p>A priority queue is unbounded, but has an internal
     48  * <i>capacity</i> governing the size of an array used to store the
     49  * elements on the queue.  It is always at least as large as the queue
     50  * size.  As elements are added to a priority queue, its capacity
     51  * grows automatically.  The details of the growth policy are not
     52  * specified.
     53  *
     54  * <p>This class and its iterator implement all of the
     55  * <em>optional</em> methods of the {@link Collection} and {@link
     56  * Iterator} interfaces.  The Iterator provided in method {@link
     57  * #iterator()} is <em>not</em> guaranteed to traverse the elements of
     58  * the priority queue in any particular order. If you need ordered
     59  * traversal, consider using {@code Arrays.sort(pq.toArray())}.
     60  *
     61  * <p><strong>Note that this implementation is not synchronized.</strong>
     62  * Multiple threads should not access a {@code PriorityQueue}
     63  * instance concurrently if any of the threads modifies the queue.
     64  * Instead, use the thread-safe {@link
     65  * java.util.concurrent.PriorityBlockingQueue} class.
     66  *
     67  * <p>Implementation note: this implementation provides
     68  * O(log(n)) time for the enqueuing and dequeuing methods
     69  * ({@code offer}, {@code poll}, {@code remove()} and {@code add});
     70  * linear time for the {@code remove(Object)} and {@code contains(Object)}
     71  * methods; and constant time for the retrieval methods
     72  * ({@code peek}, {@code element}, and {@code size}).
     73  *
     74  * <p>This class is a member of the
     75  * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
     76  * Java Collections Framework</a>.
     77  *
     78  * @since 1.5
     79  * @author Josh Bloch, Doug Lea
     80  * @param <E> the type of elements held in this queue
     81  */
     82 public class PriorityQueue<E> extends AbstractQueue<E>
     83     implements java.io.Serializable {
     84 
     85     private static final long serialVersionUID = -7720805057305804111L;
     86 
     87     private static final int DEFAULT_INITIAL_CAPACITY = 11;
     88 
     89     /**
     90      * Priority queue represented as a balanced binary heap: the two
     91      * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
     92      * priority queue is ordered by comparator, or by the elements'
     93      * natural ordering, if comparator is null: For each node n in the
     94      * heap and each descendant d of n, n <= d.  The element with the
     95      * lowest value is in queue[0], assuming the queue is nonempty.
     96      */
     97     transient Object[] queue; // non-private to simplify nested class access
     98 
     99     /**
    100      * The number of elements in the priority queue.
    101      */
    102     int size;
    103 
    104     /**
    105      * The comparator, or null if priority queue uses elements'
    106      * natural ordering.
    107      */
    108     private final Comparator<? super E> comparator;
    109 
    110     /**
    111      * The number of times this priority queue has been
    112      * <i>structurally modified</i>.  See AbstractList for gory details.
    113      */
    114     transient int modCount;     // non-private to simplify nested class access
    115 
    116     /**
    117      * Creates a {@code PriorityQueue} with the default initial
    118      * capacity (11) that orders its elements according to their
    119      * {@linkplain Comparable natural ordering}.
    120      */
    121     public PriorityQueue() {
    122         this(DEFAULT_INITIAL_CAPACITY, null);
    123     }
    124 
    125     /**
    126      * Creates a {@code PriorityQueue} with the specified initial
    127      * capacity that orders its elements according to their
    128      * {@linkplain Comparable natural ordering}.
    129      *
    130      * @param initialCapacity the initial capacity for this priority queue
    131      * @throws IllegalArgumentException if {@code initialCapacity} is less
    132      *         than 1
    133      */
    134     public PriorityQueue(int initialCapacity) {
    135         this(initialCapacity, null);
    136     }
    137 
    138     /**
    139      * Creates a {@code PriorityQueue} with the default initial capacity and
    140      * whose elements are ordered according to the specified comparator.
    141      *
    142      * @param  comparator the comparator that will be used to order this
    143      *         priority queue.  If {@code null}, the {@linkplain Comparable
    144      *         natural ordering} of the elements will be used.
    145      * @since 1.8
    146      */
    147     public PriorityQueue(Comparator<? super E> comparator) {
    148         this(DEFAULT_INITIAL_CAPACITY, comparator);
    149     }
    150 
    151     /**
    152      * Creates a {@code PriorityQueue} with the specified initial capacity
    153      * that orders its elements according to the specified comparator.
    154      *
    155      * @param  initialCapacity the initial capacity for this priority queue
    156      * @param  comparator the comparator that will be used to order this
    157      *         priority queue.  If {@code null}, the {@linkplain Comparable
    158      *         natural ordering} of the elements will be used.
    159      * @throws IllegalArgumentException if {@code initialCapacity} is
    160      *         less than 1
    161      */
    162     public PriorityQueue(int initialCapacity,
    163                          Comparator<? super E> comparator) {
    164         // Note: This restriction of at least one is not actually needed,
    165         // but continues for 1.5 compatibility
    166         if (initialCapacity < 1)
    167             throw new IllegalArgumentException();
    168         this.queue = new Object[initialCapacity];
    169         this.comparator = comparator;
    170     }
    171 
    172     /**
    173      * Creates a {@code PriorityQueue} containing the elements in the
    174      * specified collection.  If the specified collection is an instance of
    175      * a {@link SortedSet} or is another {@code PriorityQueue}, this
    176      * priority queue will be ordered according to the same ordering.
    177      * Otherwise, this priority queue will be ordered according to the
    178      * {@linkplain Comparable natural ordering} of its elements.
    179      *
    180      * @param  c the collection whose elements are to be placed
    181      *         into this priority queue
    182      * @throws ClassCastException if elements of the specified collection
    183      *         cannot be compared to one another according to the priority
    184      *         queue's ordering
    185      * @throws NullPointerException if the specified collection or any
    186      *         of its elements are null
    187      */
    188     @SuppressWarnings("unchecked")
    189     public PriorityQueue(Collection<? extends E> c) {
    190         if (c instanceof SortedSet<?>) {
    191             SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
    192             this.comparator = (Comparator<? super E>) ss.comparator();
    193             initElementsFromCollection(ss);
    194         }
    195         else if (c instanceof PriorityQueue<?>) {
    196             PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
    197             this.comparator = (Comparator<? super E>) pq.comparator();
    198             initFromPriorityQueue(pq);
    199         }
    200         else {
    201             this.comparator = null;
    202             initFromCollection(c);
    203         }
    204     }
    205 
    206     /**
    207      * Creates a {@code PriorityQueue} containing the elements in the
    208      * specified priority queue.  This priority queue will be
    209      * ordered according to the same ordering as the given priority
    210      * queue.
    211      *
    212      * @param  c the priority queue whose elements are to be placed
    213      *         into this priority queue
    214      * @throws ClassCastException if elements of {@code c} cannot be
    215      *         compared to one another according to {@code c}'s
    216      *         ordering
    217      * @throws NullPointerException if the specified priority queue or any
    218      *         of its elements are null
    219      */
    220     @SuppressWarnings("unchecked")
    221     public PriorityQueue(PriorityQueue<? extends E> c) {
    222         this.comparator = (Comparator<? super E>) c.comparator();
    223         initFromPriorityQueue(c);
    224     }
    225 
    226     /**
    227      * Creates a {@code PriorityQueue} containing the elements in the
    228      * specified sorted set.   This priority queue will be ordered
    229      * according to the same ordering as the given sorted set.
    230      *
    231      * @param  c the sorted set whose elements are to be placed
    232      *         into this priority queue
    233      * @throws ClassCastException if elements of the specified sorted
    234      *         set cannot be compared to one another according to the
    235      *         sorted set's ordering
    236      * @throws NullPointerException if the specified sorted set or any
    237      *         of its elements are null
    238      */
    239     @SuppressWarnings("unchecked")
    240     public PriorityQueue(SortedSet<? extends E> c) {
    241         this.comparator = (Comparator<? super E>) c.comparator();
    242         initElementsFromCollection(c);
    243     }
    244 
    245     private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
    246         if (c.getClass() == PriorityQueue.class) {
    247             this.queue = c.toArray();
    248             this.size = c.size();
    249         } else {
    250             initFromCollection(c);
    251         }
    252     }
    253 
    254     private void initElementsFromCollection(Collection<? extends E> c) {
    255         Object[] a = c.toArray();
    256         // If c.toArray incorrectly doesn't return Object[], copy it.
    257         if (a.getClass() != Object[].class)
    258             a = Arrays.copyOf(a, a.length, Object[].class);
    259         int len = a.length;
    260         if (len == 1 || this.comparator != null)
    261             for (Object e : a)
    262                 if (e == null)
    263                     throw new NullPointerException();
    264         this.queue = a;
    265         this.size = a.length;
    266     }
    267 
    268     /**
    269      * Initializes queue array with elements from the given Collection.
    270      *
    271      * @param c the collection
    272      */
    273     private void initFromCollection(Collection<? extends E> c) {
    274         initElementsFromCollection(c);
    275         heapify();
    276     }
    277 
    278     /**
    279      * The maximum size of array to allocate.
    280      * Some VMs reserve some header words in an array.
    281      * Attempts to allocate larger arrays may result in
    282      * OutOfMemoryError: Requested array size exceeds VM limit
    283      */
    284     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    285 
    286     /**
    287      * Increases the capacity of the array.
    288      *
    289      * @param minCapacity the desired minimum capacity
    290      */
    291     private void grow(int minCapacity) {
    292         int oldCapacity = queue.length;
    293         // Double size if small; else grow by 50%
    294         int newCapacity = oldCapacity + ((oldCapacity < 64) ?
    295                                          (oldCapacity + 2) :
    296                                          (oldCapacity >> 1));
    297         // overflow-conscious code
    298         if (newCapacity - MAX_ARRAY_SIZE > 0)
    299             newCapacity = hugeCapacity(minCapacity);
    300         queue = Arrays.copyOf(queue, newCapacity);
    301     }
    302 
    303     private static int hugeCapacity(int minCapacity) {
    304         if (minCapacity < 0) // overflow
    305             throw new OutOfMemoryError();
    306         return (minCapacity > MAX_ARRAY_SIZE) ?
    307             Integer.MAX_VALUE :
    308             MAX_ARRAY_SIZE;
    309     }
    310 
    311     /**
    312      * Inserts the specified element into this priority queue.
    313      *
    314      * @return {@code true} (as specified by {@link Collection#add})
    315      * @throws ClassCastException if the specified element cannot be
    316      *         compared with elements currently in this priority queue
    317      *         according to the priority queue's ordering
    318      * @throws NullPointerException if the specified element is null
    319      */
    320     public boolean add(E e) {
    321         return offer(e);
    322     }
    323 
    324     /**
    325      * Inserts the specified element into this priority queue.
    326      *
    327      * @return {@code true} (as specified by {@link Queue#offer})
    328      * @throws ClassCastException if the specified element cannot be
    329      *         compared with elements currently in this priority queue
    330      *         according to the priority queue's ordering
    331      * @throws NullPointerException if the specified element is null
    332      */
    333     public boolean offer(E e) {
    334         if (e == null)
    335             throw new NullPointerException();
    336         modCount++;
    337         int i = size;
    338         if (i >= queue.length)
    339             grow(i + 1);
    340         size = i + 1;
    341         if (i == 0)
    342             queue[0] = e;
    343         else
    344             siftUp(i, e);
    345         return true;
    346     }
    347 
    348     @SuppressWarnings("unchecked")
    349     public E peek() {
    350         return (size == 0) ? null : (E) queue[0];
    351     }
    352 
    353     private int indexOf(Object o) {
    354         if (o != null) {
    355             for (int i = 0; i < size; i++)
    356                 if (o.equals(queue[i]))
    357                     return i;
    358         }
    359         return -1;
    360     }
    361 
    362     /**
    363      * Removes a single instance of the specified element from this queue,
    364      * if it is present.  More formally, removes an element {@code e} such
    365      * that {@code o.equals(e)}, if this queue contains one or more such
    366      * elements.  Returns {@code true} if and only if this queue contained
    367      * the specified element (or equivalently, if this queue changed as a
    368      * result of the call).
    369      *
    370      * @param o element to be removed from this queue, if present
    371      * @return {@code true} if this queue changed as a result of the call
    372      */
    373     public boolean remove(Object o) {
    374         int i = indexOf(o);
    375         if (i == -1)
    376             return false;
    377         else {
    378             removeAt(i);
    379             return true;
    380         }
    381     }
    382 
    383     /**
    384      * Version of remove using reference equality, not equals.
    385      * Needed by iterator.remove.
    386      *
    387      * @param o element to be removed from this queue, if present
    388      * @return {@code true} if removed
    389      */
    390     boolean removeEq(Object o) {
    391         for (int i = 0; i < size; i++) {
    392             if (o == queue[i]) {
    393                 removeAt(i);
    394                 return true;
    395             }
    396         }
    397         return false;
    398     }
    399 
    400     /**
    401      * Returns {@code true} if this queue contains the specified element.
    402      * More formally, returns {@code true} if and only if this queue contains
    403      * at least one element {@code e} such that {@code o.equals(e)}.
    404      *
    405      * @param o object to be checked for containment in this queue
    406      * @return {@code true} if this queue contains the specified element
    407      */
    408     public boolean contains(Object o) {
    409         return indexOf(o) >= 0;
    410     }
    411 
    412     /**
    413      * Returns an array containing all of the elements in this queue.
    414      * The elements are in no particular order.
    415      *
    416      * <p>The returned array will be "safe" in that no references to it are
    417      * maintained by this queue.  (In other words, this method must allocate
    418      * a new array).  The caller is thus free to modify the returned array.
    419      *
    420      * <p>This method acts as bridge between array-based and collection-based
    421      * APIs.
    422      *
    423      * @return an array containing all of the elements in this queue
    424      */
    425     public Object[] toArray() {
    426         return Arrays.copyOf(queue, size);
    427     }
    428 
    429     /**
    430      * Returns an array containing all of the elements in this queue; the
    431      * runtime type of the returned array is that of the specified array.
    432      * The returned array elements are in no particular order.
    433      * If the queue fits in the specified array, it is returned therein.
    434      * Otherwise, a new array is allocated with the runtime type of the
    435      * specified array and the size of this queue.
    436      *
    437      * <p>If the queue fits in the specified array with room to spare
    438      * (i.e., the array has more elements than the queue), the element in
    439      * the array immediately following the end of the collection is set to
    440      * {@code null}.
    441      *
    442      * <p>Like the {@link #toArray()} method, this method acts as bridge between
    443      * array-based and collection-based APIs.  Further, this method allows
    444      * precise control over the runtime type of the output array, and may,
    445      * under certain circumstances, be used to save allocation costs.
    446      *
    447      * <p>Suppose {@code x} is a queue known to contain only strings.
    448      * The following code can be used to dump the queue into a newly
    449      * allocated array of {@code String}:
    450      *
    451      * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
    452      *
    453      * Note that {@code toArray(new Object[0])} is identical in function to
    454      * {@code toArray()}.
    455      *
    456      * @param a the array into which the elements of the queue are to
    457      *          be stored, if it is big enough; otherwise, a new array of the
    458      *          same runtime type is allocated for this purpose.
    459      * @return an array containing all of the elements in this queue
    460      * @throws ArrayStoreException if the runtime type of the specified array
    461      *         is not a supertype of the runtime type of every element in
    462      *         this queue
    463      * @throws NullPointerException if the specified array is null
    464      */
    465     @SuppressWarnings("unchecked")
    466     public <T> T[] toArray(T[] a) {
    467         final int size = this.size;
    468         if (a.length < size)
    469             // Make a new array of a's runtime type, but my contents:
    470             return (T[]) Arrays.copyOf(queue, size, a.getClass());
    471         System.arraycopy(queue, 0, a, 0, size);
    472         if (a.length > size)
    473             a[size] = null;
    474         return a;
    475     }
    476 
    477     /**
    478      * Returns an iterator over the elements in this queue. The iterator
    479      * does not return the elements in any particular order.
    480      *
    481      * @return an iterator over the elements in this queue
    482      */
    483     public Iterator<E> iterator() {
    484         return new Itr();
    485     }
    486 
    487     private final class Itr implements Iterator<E> {
    488         /**
    489          * Index (into queue array) of element to be returned by
    490          * subsequent call to next.
    491          */
    492         private int cursor;
    493 
    494         /**
    495          * Index of element returned by most recent call to next,
    496          * unless that element came from the forgetMeNot list.
    497          * Set to -1 if element is deleted by a call to remove.
    498          */
    499         private int lastRet = -1;
    500 
    501         /**
    502          * A queue of elements that were moved from the unvisited portion of
    503          * the heap into the visited portion as a result of "unlucky" element
    504          * removals during the iteration.  (Unlucky element removals are those
    505          * that require a siftup instead of a siftdown.)  We must visit all of
    506          * the elements in this list to complete the iteration.  We do this
    507          * after we've completed the "normal" iteration.
    508          *
    509          * We expect that most iterations, even those involving removals,
    510          * will not need to store elements in this field.
    511          */
    512         private ArrayDeque<E> forgetMeNot;
    513 
    514         /**
    515          * Element returned by the most recent call to next iff that
    516          * element was drawn from the forgetMeNot list.
    517          */
    518         private E lastRetElt;
    519 
    520         /**
    521          * The modCount value that the iterator believes that the backing
    522          * Queue should have.  If this expectation is violated, the iterator
    523          * has detected concurrent modification.
    524          */
    525         private int expectedModCount = modCount;
    526 
    527         public boolean hasNext() {
    528             return cursor < size ||
    529                 (forgetMeNot != null && !forgetMeNot.isEmpty());
    530         }
    531 
    532         @SuppressWarnings("unchecked")
    533         public E next() {
    534             if (expectedModCount != modCount)
    535                 throw new ConcurrentModificationException();
    536             if (cursor < size)
    537                 return (E) queue[lastRet = cursor++];
    538             if (forgetMeNot != null) {
    539                 lastRet = -1;
    540                 lastRetElt = forgetMeNot.poll();
    541                 if (lastRetElt != null)
    542                     return lastRetElt;
    543             }
    544             throw new NoSuchElementException();
    545         }
    546 
    547         public void remove() {
    548             if (expectedModCount != modCount)
    549                 throw new ConcurrentModificationException();
    550             if (lastRet != -1) {
    551                 E moved = PriorityQueue.this.removeAt(lastRet);
    552                 lastRet = -1;
    553                 if (moved == null)
    554                     cursor--;
    555                 else {
    556                     if (forgetMeNot == null)
    557                         forgetMeNot = new ArrayDeque<>();
    558                     forgetMeNot.add(moved);
    559                 }
    560             } else if (lastRetElt != null) {
    561                 PriorityQueue.this.removeEq(lastRetElt);
    562                 lastRetElt = null;
    563             } else {
    564                 throw new IllegalStateException();
    565             }
    566             expectedModCount = modCount;
    567         }
    568     }
    569 
    570     public int size() {
    571         return size;
    572     }
    573 
    574     /**
    575      * Removes all of the elements from this priority queue.
    576      * The queue will be empty after this call returns.
    577      */
    578     public void clear() {
    579         modCount++;
    580         for (int i = 0; i < size; i++)
    581             queue[i] = null;
    582         size = 0;
    583     }
    584 
    585     @SuppressWarnings("unchecked")
    586     public E poll() {
    587         if (size == 0)
    588             return null;
    589         int s = --size;
    590         modCount++;
    591         E result = (E) queue[0];
    592         E x = (E) queue[s];
    593         queue[s] = null;
    594         if (s != 0)
    595             siftDown(0, x);
    596         return result;
    597     }
    598 
    599     /**
    600      * Removes the ith element from queue.
    601      *
    602      * Normally this method leaves the elements at up to i-1,
    603      * inclusive, untouched.  Under these circumstances, it returns
    604      * null.  Occasionally, in order to maintain the heap invariant,
    605      * it must swap a later element of the list with one earlier than
    606      * i.  Under these circumstances, this method returns the element
    607      * that was previously at the end of the list and is now at some
    608      * position before i. This fact is used by iterator.remove so as to
    609      * avoid missing traversing elements.
    610      */
    611     @SuppressWarnings("unchecked")
    612     E removeAt(int i) {
    613         // assert i >= 0 && i < size;
    614         modCount++;
    615         int s = --size;
    616         if (s == i) // removed last element
    617             queue[i] = null;
    618         else {
    619             E moved = (E) queue[s];
    620             queue[s] = null;
    621             siftDown(i, moved);
    622             if (queue[i] == moved) {
    623                 siftUp(i, moved);
    624                 if (queue[i] != moved)
    625                     return moved;
    626             }
    627         }
    628         return null;
    629     }
    630 
    631     /**
    632      * Inserts item x at position k, maintaining heap invariant by
    633      * promoting x up the tree until it is greater than or equal to
    634      * its parent, or is the root.
    635      *
    636      * To simplify and speed up coercions and comparisons. the
    637      * Comparable and Comparator versions are separated into different
    638      * methods that are otherwise identical. (Similarly for siftDown.)
    639      *
    640      * @param k the position to fill
    641      * @param x the item to insert
    642      */
    643     private void siftUp(int k, E x) {
    644         if (comparator != null)
    645             siftUpUsingComparator(k, x);
    646         else
    647             siftUpComparable(k, x);
    648     }
    649 
    650     @SuppressWarnings("unchecked")
    651     private void siftUpComparable(int k, E x) {
    652         Comparable<? super E> key = (Comparable<? super E>) x;
    653         while (k > 0) {
    654             int parent = (k - 1) >>> 1;
    655             Object e = queue[parent];
    656             if (key.compareTo((E) e) >= 0)
    657                 break;
    658             queue[k] = e;
    659             k = parent;
    660         }
    661         queue[k] = key;
    662     }
    663 
    664     @SuppressWarnings("unchecked")
    665     private void siftUpUsingComparator(int k, E x) {
    666         while (k > 0) {
    667             int parent = (k - 1) >>> 1;
    668             Object e = queue[parent];
    669             if (comparator.compare(x, (E) e) >= 0)
    670                 break;
    671             queue[k] = e;
    672             k = parent;
    673         }
    674         queue[k] = x;
    675     }
    676 
    677     /**
    678      * Inserts item x at position k, maintaining heap invariant by
    679      * demoting x down the tree repeatedly until it is less than or
    680      * equal to its children or is a leaf.
    681      *
    682      * @param k the position to fill
    683      * @param x the item to insert
    684      */
    685     private void siftDown(int k, E x) {
    686         if (comparator != null)
    687             siftDownUsingComparator(k, x);
    688         else
    689             siftDownComparable(k, x);
    690     }
    691 
    692     @SuppressWarnings("unchecked")
    693     private void siftDownComparable(int k, E x) {
    694         Comparable<? super E> key = (Comparable<? super E>)x;
    695         int half = size >>> 1;        // loop while a non-leaf
    696         while (k < half) {
    697             int child = (k << 1) + 1; // assume left child is least
    698             Object c = queue[child];
    699             int right = child + 1;
    700             if (right < size &&
    701                 ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
    702                 c = queue[child = right];
    703             if (key.compareTo((E) c) <= 0)
    704                 break;
    705             queue[k] = c;
    706             k = child;
    707         }
    708         queue[k] = key;
    709     }
    710 
    711     @SuppressWarnings("unchecked")
    712     private void siftDownUsingComparator(int k, E x) {
    713         int half = size >>> 1;
    714         while (k < half) {
    715             int child = (k << 1) + 1;
    716             Object c = queue[child];
    717             int right = child + 1;
    718             if (right < size &&
    719                 comparator.compare((E) c, (E) queue[right]) > 0)
    720                 c = queue[child = right];
    721             if (comparator.compare(x, (E) c) <= 0)
    722                 break;
    723             queue[k] = c;
    724             k = child;
    725         }
    726         queue[k] = x;
    727     }
    728 
    729     /**
    730      * Establishes the heap invariant (described above) in the entire tree,
    731      * assuming nothing about the order of the elements prior to the call.
    732      */
    733     @SuppressWarnings("unchecked")
    734     private void heapify() {
    735         for (int i = (size >>> 1) - 1; i >= 0; i--)
    736             siftDown(i, (E) queue[i]);
    737     }
    738 
    739     /**
    740      * Returns the comparator used to order the elements in this
    741      * queue, or {@code null} if this queue is sorted according to
    742      * the {@linkplain Comparable natural ordering} of its elements.
    743      *
    744      * @return the comparator used to order this queue, or
    745      *         {@code null} if this queue is sorted according to the
    746      *         natural ordering of its elements
    747      */
    748     public Comparator<? super E> comparator() {
    749         return comparator;
    750     }
    751 
    752     /**
    753      * Saves this queue to a stream (that is, serializes it).
    754      *
    755      * @serialData The length of the array backing the instance is
    756      *             emitted (int), followed by all of its elements
    757      *             (each an {@code Object}) in the proper order.
    758      * @param s the stream
    759      * @throws java.io.IOException if an I/O error occurs
    760      */
    761     private void writeObject(java.io.ObjectOutputStream s)
    762         throws java.io.IOException {
    763         // Write out element count, and any hidden stuff
    764         s.defaultWriteObject();
    765 
    766         // Write out array length, for compatibility with 1.5 version
    767         s.writeInt(Math.max(2, size + 1));
    768 
    769         // Write out all elements in the "proper order".
    770         for (int i = 0; i < size; i++)
    771             s.writeObject(queue[i]);
    772     }
    773 
    774     /**
    775      * Reconstitutes the {@code PriorityQueue} instance from a stream
    776      * (that is, deserializes it).
    777      *
    778      * @param s the stream
    779      * @throws ClassNotFoundException if the class of a serialized object
    780      *         could not be found
    781      * @throws java.io.IOException if an I/O error occurs
    782      */
    783     private void readObject(java.io.ObjectInputStream s)
    784         throws java.io.IOException, ClassNotFoundException {
    785         // Read in size, and any hidden stuff
    786         s.defaultReadObject();
    787 
    788         // Read in (and discard) array length
    789         s.readInt();
    790 
    791         queue = new Object[size];
    792 
    793         // Read in all elements.
    794         for (int i = 0; i < size; i++)
    795             queue[i] = s.readObject();
    796 
    797         // Elements are guaranteed to be in "proper order", but the
    798         // spec has never explained what that might be.
    799         heapify();
    800     }
    801 
    802     /**
    803      * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
    804      * and <em>fail-fast</em> {@link Spliterator} over the elements in this
    805      * queue.
    806      *
    807      * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
    808      * {@link Spliterator#SUBSIZED}, and {@link Spliterator#NONNULL}.
    809      * Overriding implementations should document the reporting of additional
    810      * characteristic values.
    811      *
    812      * @return a {@code Spliterator} over the elements in this queue
    813      * @since 1.8
    814      */
    815     public final Spliterator<E> spliterator() {
    816         return new PriorityQueueSpliterator<>(this, 0, -1, 0);
    817     }
    818 
    819     static final class PriorityQueueSpliterator<E> implements Spliterator<E> {
    820         /*
    821          * This is very similar to ArrayList Spliterator, except for
    822          * extra null checks.
    823          */
    824         private final PriorityQueue<E> pq;
    825         private int index;            // current index, modified on advance/split
    826         private int fence;            // -1 until first use
    827         private int expectedModCount; // initialized when fence set
    828 
    829         /** Creates new spliterator covering the given range. */
    830         PriorityQueueSpliterator(PriorityQueue<E> pq, int origin, int fence,
    831                                  int expectedModCount) {
    832             this.pq = pq;
    833             this.index = origin;
    834             this.fence = fence;
    835             this.expectedModCount = expectedModCount;
    836         }
    837 
    838         private int getFence() { // initialize fence to size on first use
    839             int hi;
    840             if ((hi = fence) < 0) {
    841                 expectedModCount = pq.modCount;
    842                 hi = fence = pq.size;
    843             }
    844             return hi;
    845         }
    846 
    847         public PriorityQueueSpliterator<E> trySplit() {
    848             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
    849             return (lo >= mid) ? null :
    850                 new PriorityQueueSpliterator<>(pq, lo, index = mid,
    851                                                expectedModCount);
    852         }
    853 
    854         @SuppressWarnings("unchecked")
    855         public void forEachRemaining(Consumer<? super E> action) {
    856             int i, hi, mc; // hoist accesses and checks from loop
    857             PriorityQueue<E> q; Object[] a;
    858             if (action == null)
    859                 throw new NullPointerException();
    860             if ((q = pq) != null && (a = q.queue) != null) {
    861                 if ((hi = fence) < 0) {
    862                     mc = q.modCount;
    863                     hi = q.size;
    864                 }
    865                 else
    866                     mc = expectedModCount;
    867                 if ((i = index) >= 0 && (index = hi) <= a.length) {
    868                     for (E e;; ++i) {
    869                         if (i < hi) {
    870                             if ((e = (E) a[i]) == null) // must be CME
    871                                 break;
    872                             action.accept(e);
    873                         }
    874                         else if (q.modCount != mc)
    875                             break;
    876                         else
    877                             return;
    878                     }
    879                 }
    880             }
    881             throw new ConcurrentModificationException();
    882         }
    883 
    884         public boolean tryAdvance(Consumer<? super E> action) {
    885             if (action == null)
    886                 throw new NullPointerException();
    887             int hi = getFence(), lo = index;
    888             if (lo >= 0 && lo < hi) {
    889                 index = lo + 1;
    890                 @SuppressWarnings("unchecked") E e = (E)pq.queue[lo];
    891                 if (e == null)
    892                     throw new ConcurrentModificationException();
    893                 action.accept(e);
    894                 if (pq.modCount != expectedModCount)
    895                     throw new ConcurrentModificationException();
    896                 return true;
    897             }
    898             return false;
    899         }
    900 
    901         public long estimateSize() {
    902             return (long) (getFence() - index);
    903         }
    904 
    905         public int characteristics() {
    906             return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.NONNULL;
    907         }
    908     }
    909 }
    910