Class MinMaxPriorityQueue<E>

java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractQueue<E>
com.google.common.collect.MinMaxPriorityQueue<E>
All Implemented Interfaces:
Iterable<E>, Collection<E>, Queue<E>

public final class MinMaxPriorityQueue<E> extends AbstractQueue<E>
A double-ended priority queue, which provides constant-time access to both its least element and its greatest element, as determined by the queue's specified comparator. If no comparator is given at creation time, the natural order of elements is used. If no maximum size is given at creation time, the queue is unbounded.

Usage example:


 MinMaxPriorityQueue<User> users = MinMaxPriorityQueue.orderedBy(userComparator)
     .maximumSize(1000)
     .create();
 

As a Queue it functions exactly as a PriorityQueue: its head element -- the implicit target of the methods peek(), poll() and AbstractQueue.remove() -- is defined as the least element in the queue according to the queue's comparator. But unlike a regular priority queue, the methods peekLast(), pollLast() and removeLast() are also provided, to act on the greatest element in the queue instead.

A min-max priority queue can be configured with a maximum size. If so, each time the size of the queue exceeds that value, the queue automatically removes its greatest element according to its comparator (which might be the element that was just added). This is different from conventional bounded queues, which either block or reject new elements when full.

This implementation is based on the min-max heap developed by Atkinson, et al. Unlike many other double-ended priority queues, it stores elements in a single array, as compact as the traditional heap data structure used in PriorityQueue.

This class is not thread-safe, and does not accept null elements.

Performance notes:

Since:
8.0
  • Field Details

  • Constructor Details

  • Method Details

    • create

      public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create()
      Creates a new min-max priority queue with default settings: natural order, no maximum size, no initial contents, and an initial expected size of 11.
    • create

      public static <E extends Comparable<E>> MinMaxPriorityQueue<E> create(Iterable<? extends E> initialContents)
      Creates a new min-max priority queue using natural order, no maximum size, and initially containing the given elements.
    • orderedBy

      public static <B> MinMaxPriorityQueue.Builder<B> orderedBy(Comparator<B> comparator)
      Creates and returns a new builder, configured to build MinMaxPriorityQueue instances that use comparator to determine the least and greatest elements.
    • expectedSize

      public static MinMaxPriorityQueue.Builder<Comparable> expectedSize(int expectedSize)
      Creates and returns a new builder, configured to build MinMaxPriorityQueue instances sized appropriately to hold expectedSize elements.
    • maximumSize

      public static MinMaxPriorityQueue.Builder<Comparable> maximumSize(int maximumSize)
      Creates and returns a new builder, configured to build MinMaxPriorityQueue instances that are limited to maximumSize elements. Each time a queue grows beyond this bound, it immediately removes its greatest element (according to its comparator), which might be the element that was just added.
    • size

      public int size()
      Specified by:
      size in interface Collection<E>
      Specified by:
      size in class AbstractCollection<E>
    • add

      public boolean add(E element)
      Adds the given element to this queue. If this queue has a maximum size, after adding element the queue will automatically evict its greatest element (according to its comparator), which may be element itself.
      Specified by:
      add in interface Collection<E>
      Specified by:
      add in interface Queue<E>
      Overrides:
      add in class AbstractQueue<E>
      Returns:
      true always
    • addAll

      public boolean addAll(Collection<? extends E> newElements)
      Specified by:
      addAll in interface Collection<E>
      Overrides:
      addAll in class AbstractQueue<E>
    • offer

      public boolean offer(E element)
      Adds the given element to this queue. If this queue has a maximum size, after adding element the queue will automatically evict its greatest element (according to its comparator), which may be element itself.
    • poll

      @CheckForNull public E poll()
    • elementData

      E elementData(int index)
    • peek

      @CheckForNull public E peek()
    • getMaxElementIndex

      private int getMaxElementIndex()
      Returns the index of the max element.
    • pollFirst

      @CheckForNull public E pollFirst()
      Removes and returns the least element of this queue, or returns null if the queue is empty.
    • removeFirst

      public E removeFirst()
      Removes and returns the least element of this queue.
      Throws:
      NoSuchElementException - if the queue is empty
    • peekFirst

      @CheckForNull public E peekFirst()
      Retrieves, but does not remove, the least element of this queue, or returns null if the queue is empty.
    • pollLast

      @CheckForNull public E pollLast()
      Removes and returns the greatest element of this queue, or returns null if the queue is empty.
    • removeLast

      public E removeLast()
      Removes and returns the greatest element of this queue.
      Throws:
      NoSuchElementException - if the queue is empty
    • peekLast

      @CheckForNull public E peekLast()
      Retrieves, but does not remove, the greatest element of this queue, or returns null if the queue is empty.
    • removeAt

      @CheckForNull MinMaxPriorityQueue.MoveDesc<E> removeAt(int index)
      Removes the element at position index.

      Normally this method leaves the elements at up to index - 1, inclusive, untouched. Under these circumstances, it returns null.

      Occasionally, in order to maintain the heap invariant, it must swap a later element of the list with one before index. Under these circumstances it returns a pair of elements as a MinMaxPriorityQueue.MoveDesc. The first one is the element that was previously at the end of the heap and is now at some position before index. The second element is the one that was swapped down to replace the element at index. This fact is used by iterator.remove so as to visit elements during a traversal once and only once.

    • fillHole

      @CheckForNull private MinMaxPriorityQueue.MoveDesc<E> fillHole(int index, E toTrickle)
    • removeAndGet

      private E removeAndGet(int index)
      Removes and returns the value at index.
    • heapForIndex

      private MinMaxPriorityQueue<E>.Heap heapForIndex(int i)
    • isEvenLevel

      static boolean isEvenLevel(int index)
    • isIntact

      boolean isIntact()
      Returns true if the MinMax heap structure holds. This is only used in testing.

      TODO(kevinb): move to the test class?

    • iterator

      public Iterator<E> iterator()
      Returns an iterator over the elements contained in this collection, in no particular order.

      The iterator is fail-fast: If the MinMaxPriorityQueue is modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will generally throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

      Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

      Specified by:
      iterator in interface Collection<E>
      Specified by:
      iterator in interface Iterable<E>
      Specified by:
      iterator in class AbstractCollection<E>
      Returns:
      an iterator over the elements contained in this collection
    • clear

      public void clear()
      Specified by:
      clear in interface Collection<E>
      Overrides:
      clear in class AbstractQueue<E>
    • toArray

      public Object[] toArray()
      Specified by:
      toArray in interface Collection<E>
      Overrides:
      toArray in class AbstractCollection<E>
    • comparator

      public Comparator<? super E> comparator()
      Returns the comparator used to order the elements in this queue. Obeys the general contract of PriorityQueue.comparator, but returns Ordering.natural() instead of null to indicate natural ordering.
    • capacity

      int capacity()
    • initialQueueSize

      static int initialQueueSize(int configuredExpectedSize, int maximumSize, Iterable<?> initialContents)
    • growIfNeeded

      private void growIfNeeded()
    • calculateNewCapacity

      private int calculateNewCapacity()
      Returns ~2x the old capacity if small; ~1.5x otherwise.
    • capAtMaximumSize

      private static int capAtMaximumSize(int queueSize, int maximumSize)
      There's no reason for the queueSize to ever be more than maxSize + 1