Java集合源码分析(十一)-Queue

157 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

源码

package java.util;

/**
 * A collection designed for holding elements prior to processing.
 * Besides basic {@link java.util.Collection Collection} operations,
 * queues provide additional insertion, extraction, and inspection
 * operations.  Each of these methods exists in two forms: one throws
 * an exception if the operation fails, the other returns a special
 * value (either {@code null} or {@code false}, depending on the
 * operation).  The latter form of the insert operation is designed
 * specifically for use with capacity-restricted {@code Queue}
 * implementations; in most implementations, insert operations cannot
 * fail.
 *
 * <table BORDER CELLPADDING=3 CELLSPACING=1>
 * <caption>Summary of Queue methods</caption>
 *  <tr>
 *    <td></td>
 *    <td ALIGN=CENTER><em>Throws exception</em></td>
 *    <td ALIGN=CENTER><em>Returns special value</em></td>
 *  </tr>
 *  <tr>
 *    <td><b>Insert</b></td>
 *    <td>{@link Queue#add add(e)}</td>
 *    <td>{@link Queue#offer offer(e)}</td>
 *  </tr>
 *  <tr>
 *    <td><b>Remove</b></td>
 *    <td>{@link Queue#remove remove()}</td>
 *    <td>{@link Queue#poll poll()}</td>
 *  </tr>
 *  <tr>
 *    <td><b>Examine</b></td>
 *    <td>{@link Queue#element element()}</td>
 *    <td>{@link Queue#peek peek()}</td>
 *  </tr>
 * </table>
 *
 * <p>Queues typically, but do not necessarily, order elements in a
 * FIFO (first-in-first-out) manner.  Among the exceptions are
 * priority queues, which order elements according to a supplied
 * comparator, or the elements' natural ordering, and LIFO queues (or
 * stacks) which order the elements LIFO (last-in-first-out).
 * Whatever the ordering used, the <em>head</em> of the queue is that
 * element which would be removed by a call to {@link #remove() } or
 * {@link #poll()}.  In a FIFO queue, all new elements are inserted at
 * the <em>tail</em> of the queue. Other kinds of queues may use
 * different placement rules.  Every {@code Queue} implementation
 * must specify its ordering properties.
 *
 * <p>The {@link #offer offer} method inserts an element if possible,
 * otherwise returning {@code false}.  This differs from the {@link
 * java.util.Collection#add Collection.add} method, which can fail to
 * add an element only by throwing an unchecked exception.  The
 * {@code offer} method is designed for use when failure is a normal,
 * rather than exceptional occurrence, for example, in fixed-capacity
 * (or &quot;bounded&quot;) queues.
 *
 * <p>The {@link #remove()} and {@link #poll()} methods remove and
 * return the head of the queue.
 * Exactly which element is removed from the queue is a
 * function of the queue's ordering policy, which differs from
 * implementation to implementation. The {@code remove()} and
 * {@code poll()} methods differ only in their behavior when the
 * queue is empty: the {@code remove()} method throws an exception,
 * while the {@code poll()} method returns {@code null}.
 *
 * <p>The {@link #element()} and {@link #peek()} methods return, but do
 * not remove, the head of the queue.
 *
 * <p>The {@code Queue} interface does not define the <i>blocking queue
 * methods</i>, which are common in concurrent programming.  These methods,
 * which wait for elements to appear or for space to become available, are
 * defined in the {@link java.util.concurrent.BlockingQueue} interface, which
 * extends this interface.
 *
 * <p>{@code Queue} implementations generally do not allow insertion of {@code null} elements, although some implementations, such as
 * {@link LinkedList}, do not prohibit insertion of {@code null}.
 * Even in the implementations that permit it, {@code null} should
 * not be inserted into a {@code Queue}, as {@code null} is also
 * used as a special return value by the {@code poll} method to
 * indicate that the queue contains no elements.
 *
 * <p>{@code Queue} implementations generally do not define element-based versions of methods {@code equals} and {@code hashCode} but instead inherit the identity based versions from class {@code Object}, because element-based equality is not always well-defined for queues with the same elements but different ordering properties.
 *
 *
 * <p>This interface is a member of the Java Collections Framework
 *
 * @see java.util.Collection
 * @see LinkedList
 * @see PriorityQueue
 * @see java.util.concurrent.LinkedBlockingQueue
 * @see java.util.concurrent.BlockingQueue
 * @see java.util.concurrent.ArrayBlockingQueue
 * @see java.util.concurrent.LinkedBlockingQueue
 * @see java.util.concurrent.PriorityBlockingQueue
 * @since 1.5
 * @author Doug Lea
 * @param <E> the type of elements held in this collection
 */
public interface Queue<E> extends Collection<E> {
    /**
     * Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions, returning {@code true} upon success and throwing an {@code IllegalStateException} if no space is currently available.
     *
     * @param e the element to add
     * @return {@code true} (as specified by {@link Collection#add})
     * @throws IllegalStateException if the element cannot be added at this time due to capacity restrictions
     * @throws ClassCastException if the class of the specified element prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null and this queue does not permit null elements
     * @throws IllegalArgumentException if some property of this element prevents it from being added to this queue
     */
    boolean add(E e);

    /**
     * Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions.
     * When using a capacity-restricted queue, this method is generally preferable to {@link #add}, which can fail to insert an element only by throwing an exception.
     *
     * @param e the element to add
     * @return {@code true} if the element was added to this queue, else {@code false}
     * @throws ClassCastException if the class of the specified element prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null and this queue does not permit null elements
     * @throws IllegalArgumentException if some property of this element prevents it from being added to this queue
     */
    boolean offer(E e);

    /**
     * Retrieves and removes the head of this queue.  
     * This method differs from {@link #poll poll} only in that it throws an exception if this queue is empty.
     *
     * @return the head of this queue
     * @throws NoSuchElementException if this queue is empty
     */
    E remove();

    /**
     * Retrieves and removes the head of this queue, or returns {@code null} if this queue is empty.
     *
     * @return the head of this queue, or {@code null} if this queue is empty
     */
    E poll();

    /**
     * Retrieves, but does not remove, the head of this queue.  
     * This method differs from {@link #peek peek} only in that it throws an exception if this queue is empty.
     *
     * @return the head of this queue
     * @throws NoSuchElementException if this queue is empty
     */
    E element();

    /**
     * Retrieves, but does not remove, the head of this queue, or returns {@code null} if this queue is empty.
     *
     * @return the head of this queue, or {@code null} if this queue is empty
     */
    E peek();
}

注释内容

  • 设计用于在处理前保存元素的集合
  • 除了基础的集合操作,队列提供额外的插入、提取和查看操作。每一个这些方法都有两种形式:一种是抛出异常如果这个操作失败,另一种是返回特殊值(null 或 false,取决于操作)。后一种形式的插入操作是专门设计用于容量受限的队列实现;在大多数实现,插入操作不能失败
  • 队列通常,但不是必须,使用 FIFO(first-in-first-out)方式排序元素。例外情况包括优先队列,根据提供的比较器或元素的自然排序对元素进行排序,和排序队列 LIFO(last-in-first-out)的 LIFO 队列(或栈)
  • 无论使用哪种排序,队列的头将通过调用 remove()poll() 移除。在 FIFO 队列,全部新元素插入到队列的尾部,其他类型队列可能使用不同的放置规则。每个队列实现必须明确规定它的排序属性
  • offer 方法插入一个元素,否则返回 false。这和 Collection.add 方法不同,offer 方法可以通过抛出未经检查异常使得添加元素失败,offer 方法设计用于正常失败而非异常引起,例如,在固定容量(或者”有界“)队列
  • remove()poll() 方法移除和返回队列的头。准确的说,从队列中移除哪一个元素是队列排序策略的功能,不同的实现是不同的。remove()poll() 方法只有在队列为空的时候行为不同,remove()方法抛异常,而 poll() 方法返回 null
  • element()peek() 方法返回,但没有移除队列的头
  • Queue 接口没有定义阻塞的队列方法,这在并发编程中很常见,这些等待元素出现和空间可用的方法被定义在扩展这个接口的 java.util.concurrent.BlockingQueue 接口
  • Queue 实现通常不允许插入 null 元素,尽管一些实现,例如 LinkedList,不禁止插入 null,即使在允许插入 null 值的实现,null 不应该插入队列,因为 null 同样用于 poll 方法的一个特殊返回值,指明队列不包含元素
  • 队列实现通常不定义方法 equals 和 hashCode 基于元素的版本,而是从 Object 类继承基于身份的版本,因为对于具有相同元素但排列属性不同的队列,基于元素的相等不是总定义清晰
Throws exceptionReturns special value
Insertadd(e)offer(e)
Removeremove()poll()
Examineelement()peek()

方法总结

  • boolean add(E e):如果在不违反容量限制的情况下立即插入指定元素到队列,成功返回 true,和如果当前没有可用空间抛出 IllegalStateException
  • boolean offer(E e):如果在不违反容量限制的情况下立即插入指定元素到队列,当使用容量受限的队列,这个方法通常更加适合添加,只有通过抛出异常才能失败插入元素
  • E remove():检索和移除这个队列的头,这个方法和 poll 的区别只有当这个队列是空,它抛出异常
  • E poll():检索和移除这个队列的头,或者返回 null 如果这个队列是空
  • E element():检索但不移除这个队列的头,这个方法和 peek 的区别只有当这个队列是空,它抛出异常
  • E peek():检索但不移除这个队列的头,如果这个队列是空,返回 null