ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/PriorityQueue.java
(Generate patch)

Comparing jsr166/src/main/java/util/PriorityQueue.java (file contents):
Revision 1.83 by jsr166, Sat Jan 19 17:33:55 2013 UTC vs.
Revision 1.102 by jsr166, Wed Dec 31 07:54:13 2014 UTC

# Line 24 | Line 24
24   */
25  
26   package java.util;
27 +
28 + import java.util.function.Consumer;
29   import java.util.stream.Stream;
28 import java.util.Spliterator;
29 import java.util.stream.Streams;
30 import java.util.function.Block;
30  
31   /**
32   * An unbounded priority {@linkplain Queue queue} based on a priority heap.
# Line 67 | Line 66 | import java.util.function.Block;
66   * java.util.concurrent.PriorityBlockingQueue} class.
67   *
68   * <p>Implementation note: this implementation provides
69 < * O(log(n)) time for the enqueing and dequeing methods
69 > * O(log(n)) time for the enqueuing and dequeuing methods
70   * ({@code offer}, {@code poll}, {@code remove()} and {@code add});
71   * linear time for the {@code remove(Object)} and {@code contains(Object)}
72   * methods; and constant time for the retrieval methods
# Line 79 | Line 78 | import java.util.function.Block;
78   *
79   * @since 1.5
80   * @author Josh Bloch, Doug Lea
81 < * @param <E> the type of elements held in this collection
81 > * @param <E> the type of elements held in this queue
82   */
83   public class PriorityQueue<E> extends AbstractQueue<E>
84      implements java.io.Serializable {
# Line 101 | Line 100 | public class PriorityQueue<E> extends Ab
100      /**
101       * The number of elements in the priority queue.
102       */
103 <    private int size = 0;
103 >    private int size;
104  
105      /**
106       * The comparator, or null if priority queue uses elements'
# Line 395 | Line 394 | public class PriorityQueue<E> extends Ab
394       * @return {@code true} if this queue contains the specified element
395       */
396      public boolean contains(Object o) {
397 <        return indexOf(o) != -1;
397 >        return indexOf(o) >= 0;
398      }
399  
400      /**
# Line 451 | Line 450 | public class PriorityQueue<E> extends Ab
450       *         this queue
451       * @throws NullPointerException if the specified array is null
452       */
453 +    @SuppressWarnings("unchecked")
454      public <T> T[] toArray(T[] a) {
455 +        final int size = this.size;
456          if (a.length < size)
457              // Make a new array of a's runtime type, but my contents:
458              return (T[]) Arrays.copyOf(queue, size, a.getClass());
# Line 476 | Line 477 | public class PriorityQueue<E> extends Ab
477           * Index (into queue array) of element to be returned by
478           * subsequent call to next.
479           */
480 <        private int cursor = 0;
480 >        private int cursor;
481  
482          /**
483           * Index of element returned by most recent call to next,
# Line 496 | Line 497 | public class PriorityQueue<E> extends Ab
497           * We expect that most iterations, even those involving removals,
498           * will not need to store elements in this field.
499           */
500 <        private ArrayDeque<E> forgetMeNot = null;
500 >        private ArrayDeque<E> forgetMeNot;
501  
502          /**
503           * Element returned by the most recent call to next iff that
504           * element was drawn from the forgetMeNot list.
505           */
506 <        private E lastRetElt = null;
506 >        private E lastRetElt;
507  
508          /**
509           * The modCount value that the iterator believes that the backing
# Line 541 | Line 542 | public class PriorityQueue<E> extends Ab
542                      cursor--;
543                  else {
544                      if (forgetMeNot == null)
545 <                        forgetMeNot = new ArrayDeque<E>();
545 >                        forgetMeNot = new ArrayDeque<>();
546                      forgetMeNot.add(moved);
547                  }
548              } else if (lastRetElt != null) {
# Line 743 | Line 744 | public class PriorityQueue<E> extends Ab
744       *             emitted (int), followed by all of its elements
745       *             (each an {@code Object}) in the proper order.
746       * @param s the stream
747 +     * @throws java.io.IOException if an I/O error occurs
748       */
749      private void writeObject(java.io.ObjectOutputStream s)
750          throws java.io.IOException {
# Line 762 | Line 764 | public class PriorityQueue<E> extends Ab
764       * (that is, deserializes it).
765       *
766       * @param s the stream
767 +     * @throws ClassNotFoundException if the class of a serialized object
768 +     *         could not be found
769 +     * @throws java.io.IOException if an I/O error occurs
770       */
771      private void readObject(java.io.ObjectInputStream s)
772          throws java.io.IOException, ClassNotFoundException {
# Line 782 | Line 787 | public class PriorityQueue<E> extends Ab
787          heapify();
788      }
789  
790 <    // wrapping constructor in method avoids transient javac problems
791 <    final PriorityQueueSpliterator<E> spliterator(int origin, int fence,
792 <                                                  int expectedModCount) {
793 <        return new PriorityQueueSpliterator<E>(this, origin, fence,
794 <                                               expectedModCount);
795 <    }
796 <
797 <    public Stream<E> stream() {
798 <        int flags = Streams.STREAM_IS_SIZED;
794 <        return Streams.stream
795 <            (() -> spliterator(0, size, modCount), flags);
796 <    }
797 <    public Stream<E> parallelStream() {
798 <        int flags = Streams.STREAM_IS_SIZED;
799 <        return Streams.parallelStream
800 <            (() -> spliterator(0, size, modCount), flags);
801 <    }
802 <
803 <    /** Index-based split-by-two Spliterator */
804 <    static final class PriorityQueueSpliterator<E>
805 <        implements Spliterator<E>, Iterator<E> {
790 >    public Spliterator<E> spliterator() {
791 >        return new PriorityQueueSpliterator<E>(this, 0, -1, 0);
792 >    }
793 >
794 >    /**
795 >     * This is very similar to ArrayList Spliterator, except for extra
796 >     * null checks.
797 >     */
798 >    static final class PriorityQueueSpliterator<E> implements Spliterator<E> {
799          private final PriorityQueue<E> pq;
800 <        private int index;           // current index, modified on advance/split
801 <        private final int fence;     // one past last index
802 <        private final int expectedModCount; // for comodification checks
800 >        private int index;            // current index, modified on advance/split
801 >        private int fence;            // -1 until first use
802 >        private int expectedModCount; // initialized when fence set
803  
804 <        /** Create new spliterator covering the given  range */
804 >        /** Creates new spliterator covering the given range */
805          PriorityQueueSpliterator(PriorityQueue<E> pq, int origin, int fence,
806                               int expectedModCount) {
807 <            this.pq = pq; this.index = origin; this.fence = fence;
807 >            this.pq = pq;
808 >            this.index = origin;
809 >            this.fence = fence;
810              this.expectedModCount = expectedModCount;
811          }
812  
813 <        public PriorityQueueSpliterator<E> trySplit() {
814 <            int lo = index, mid = (lo + fence) >>> 1;
813 >        private int getFence() { // initialize fence to size on first use
814 >            int hi;
815 >            if ((hi = fence) < 0) {
816 >                expectedModCount = pq.modCount;
817 >                hi = fence = pq.size;
818 >            }
819 >            return hi;
820 >        }
821 >
822 >        public Spliterator<E> trySplit() {
823 >            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
824              return (lo >= mid) ? null :
825                  new PriorityQueueSpliterator<E>(pq, lo, index = mid,
826 <                                            expectedModCount);
826 >                                                expectedModCount);
827          }
828  
829 <        public void forEach(Block<? super E> block) {
830 <            Object[] a; int i, hi; // hoist accesses and checks from loop
831 <            if (block == null)
829 >        @SuppressWarnings("unchecked")
830 >        public void forEachRemaining(Consumer<? super E> action) {
831 >            int i, hi, mc; // hoist accesses and checks from loop
832 >            PriorityQueue<E> q; Object[] a;
833 >            if (action == null)
834                  throw new NullPointerException();
835 <            if ((a = pq.queue).length >= (hi = fence) &&
836 <                (i = index) >= 0 && i < hi) {
837 <                index = hi;
838 <                do {
839 <                    @SuppressWarnings("unchecked") E e = (E) a[i];
840 <                    block.accept(e);
841 <                } while (++i < hi);
842 <                if (pq.modCount != expectedModCount)
843 <                    throw new ConcurrentModificationException();
835 >            if ((q = pq) != null && (a = q.queue) != null) {
836 >                if ((hi = fence) < 0) {
837 >                    mc = q.modCount;
838 >                    hi = q.size;
839 >                }
840 >                else
841 >                    mc = expectedModCount;
842 >                if ((i = index) >= 0 && (index = hi) <= a.length) {
843 >                    for (E e;; ++i) {
844 >                        if (i < hi) {
845 >                            if ((e = (E) a[i]) == null) // must be CME
846 >                                break;
847 >                            action.accept(e);
848 >                        }
849 >                        else if (q.modCount != mc)
850 >                            break;
851 >                        else
852 >                            return;
853 >                    }
854 >                }
855              }
856 +            throw new ConcurrentModificationException();
857          }
858  
859 <        public boolean tryAdvance(Block<? super E> block) {
860 <            if (index >= 0 && index < fence) {
859 >        public boolean tryAdvance(Consumer<? super E> action) {
860 >            int hi = getFence(), lo = index;
861 >            if (lo >= 0 && lo < hi) {
862 >                index = lo + 1;
863 >                @SuppressWarnings("unchecked") E e = (E)pq.queue[lo];
864 >                if (e == null)
865 >                    throw new ConcurrentModificationException();
866 >                action.accept(e);
867                  if (pq.modCount != expectedModCount)
868                      throw new ConcurrentModificationException();
845                @SuppressWarnings("unchecked") E e =
846                    (E)pq.queue[index++];
847                block.accept(e);
869                  return true;
870              }
871              return false;
872          }
873  
874 <        public long estimateSize() { return (long)(fence - index); }
875 <        public boolean hasExactSize() { return true; }
876 <        public boolean hasExactSplits() { return true; }
856 <
857 <        // Iterator support
858 <        public Iterator<E> iterator() { return this; }
859 <        public void remove() { throw new UnsupportedOperationException(); }
860 <        public boolean hasNext() { return index >= 0 && index < fence; }
874 >        public long estimateSize() {
875 >            return (long) (getFence() - index);
876 >        }
877  
878 <        public E next() {
879 <            if (index < 0 || index >= fence)
864 <                throw new NoSuchElementException();
865 <            if (pq.modCount != expectedModCount)
866 <                throw new ConcurrentModificationException();
867 <            @SuppressWarnings("unchecked") E e =
868 <                (E) pq.queue[index++];
869 <            return e;
878 >        public int characteristics() {
879 >            return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.NONNULL;
880          }
881      }
882   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines