[集合類]源碼解析6(Queue接口、AbstractQueue抽象類、Deque接口)

上一篇:[集合類]源碼解析5(ArrayList類、Vector類和Stack類)

1. Queue接口

Queue接口主要定義了隊列的基本方法,下面我們分析註釋,瞭解其實現、使用規則。

/**
 * 設計用於在處理之前保留元素的集合。 除了基本的Collection操作之外,隊列還提供額外的插入,提取和檢查操作。 
 * 這些方法中的每一種都有兩種形式:如果操作失敗,則拋出一個異常,
 * 另一種形式返回一個特殊值( null或false ,具體取決於操作)。 
 * 插入操作的後一種形式專門設計用於容量限制的Queue實現; 在大多數實現中,插入操作不能失敗。 
 *
 * 隊列通常(但不一定)是以FIFO(先進先出)方式排序元素。 
 * 例外情況包括優先級隊列(根據提供的比較器對元素進行排序)和LIFO隊列(或堆棧)(後進先出)。
 * 無論使用什麼順序,隊列的頭都是通過調用remove()或poll()刪除的元素。 
 * 在一個FIFO隊列,所有新元素插入到隊列的尾部。其他類型的隊列可能使用不同的佈局規則。
 * 每個Queue實現必須指定其排序屬性。
 *
 * offer方法插入一個元素,如果失敗返回false。這與Collection.add方法失敗只能通過拋出異常不同。
 * offer方法設計在故障情況下是正常的,而不是發生異常,例如在固定容量(或“有界”)隊列中。 
 * 
 * remove()和poll()方法刪除並返回隊列的頭。從隊列中刪除哪個元素是隊列排序策略的一個功能,它與實現不同。
 * remove()和poll()方法在隊列爲空時的行爲不同:remove()方法拋出異常,而poll()方法返回null 。 
 * 
 * element()和peek()方法返回隊列的頭元素,但不刪除。
 * 
 * Queue接口沒有定義在併發編程中是常見的阻塞隊列方法。
 * 這些方法(等待元素添加或有空間可用)在BlockingQueue接口中定義,該接口擴展了此接口。
 * 
 * Queue實現通常不允許插入null元素,儘管一些實現(例如LinkedList)允許插入null。
 * 即使在允許它的實現中,null也不應該插入到Queue中,
 * 因爲null也被poll方法用作特殊的返回值,表明隊列不包含元素。
 *
 * Queue實現通常不定義基於元素的equals方法和hashCode方法,而是從類別Object繼承基於標識的版本,
 * 因爲對於具有相同元素但不同排序屬性的隊列,基於元素的等式並不總是定義良好。
 */
public interface Queue<E> extends Collection<E> {
    /**
     * 插入指定元素到隊列中,如果不會違反容量限制,在成功後返回true
     * 如果沒有空間可用,拋出IllegalStateException異常
     * @param e the element to add
     * @return {@code true} (as specified by {@link Collection#add})
     * @throws IllegalStateException 由於容量限制,元素不能被添加
     * @throws ClassCastException 如果指定元素的類阻止將其添加到此隊列中
     * @throws NullPointerException 如果指定的元素爲空,並且此隊列不允許添加空元素
     * @throws IllegalArgumentException 如果此元素的某些屬性阻止將其添加到此隊列中
     */
    boolean add(E e);

    /**
     * 插入指定元素到隊列中,如果不會違反容量限制
     * 當使用容量受限的隊列時,此方法通常比add方法更可取,後者插入元素失敗拋出異常。
     * @param e the element to add
     * @return 如果元素被添加到此隊列,則爲true,否則爲false
     * @throws ClassCastException 如果指定元素的類阻止將其添加到此隊列中
     * @throws NullPointerException 如果指定的元素爲空,並且此隊列不允許添加空元素
     * @throws IllegalArgumentException 如果此元素的某些屬性阻止將其添加到此隊列中
     */
    boolean offer(E e);

    /**
     * 返回並刪除隊列的頭元素。這個方法和poll方法不同的地方僅在於如果隊列爲空的話,remove方法會拋出異常。
     * @throws NoSuchElementException 如果隊列爲空
     */
    E remove();

    /**
     * 返回並刪除隊列的頭元素,如果隊列爲空,返回null。
     */
    E poll();

    /**
     * 返回隊列頭元素,但是不刪除他。這個方法和peek方法的唯一區別是,當隊列爲空時,element方法會拋出異常。
     * @throws NoSuchElementException 如果隊列爲空
     */
    E element();

    /**
     * 返回隊列的頭元素,但不刪除他,如果隊列爲空的話,返回null。
     */
    E peek();
}

2. AbstractQueue 抽象類

/**
 * 該類提供一些隊列操作的框架實現。
 * 當基本實現不允許空元素時,該類中的實現是適當的。
 * add方法、remove方法和element方法分別基於offer方法、poll方法、peek方法
 * 但是通過拋出異常而不是返回false或null來表明失敗
 *
 * 擴展這個類的隊列實現必須最少定義一個不允許插入null元素的offer方法,以及peek、poll、size、itertor方法。
 * 通常還會重寫其他方法。如果不能滿足這些需求,可以考慮子類化AbstractCollection
 */
public abstract class AbstractQueue<E>
    extends AbstractCollection<E>
    implements Queue<E> {

    /**
     * 給子類使用的構造器
     */
    protected AbstractQueue() {
    }

    /**
     * 如果offer成功,返回true,否則拋出IllegalStateException異常
     */
    public boolean add(E e) {
      	// 基於offer方法
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

    /**
     * 返回poll的結果,除非隊列爲空
     */
    public E remove() {
      	// 基於poll方法
        E x = poll();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }

    /**
     * 返回peek的結果,除非隊列爲空
     */
    public E element() {
      	// 基於peek方法
        E x = peek();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }

    /**
     * 刪除隊列中所有元素,重複調用poll方法,直到其返回null
     */
    public void clear() {
        while (poll() != null)
            ;
    }

    /**
     * 將指定集合中的所有元素添加到此隊列。
     * 試圖將所有隊列添加到自身會導致IllegalArgumentException。
     * 此外,如果在操作進行過程中修改了指定的集合,則此操作的行爲是未定義的。
     *
     * 此實現遍歷指定的集合,並依次將迭代器返回的每個元素添加到此隊列。
     * 在嘗試添加元素(特別是包含null元素)時遇到的運行時異常可能會導致在拋出異常時成功添加了一部分元素。 
     *
     * @param c 包含要添加到隊列中的元素
     * @return 如果此隊列因調用而更改,返回true
     * @throws ClassCastException 如果指定集合的元素的類阻止將其添加到此隊列中
     * @throws NullPointerException 如果指定的集合包含空元素,且此隊列不允許空元素,或者指定的集合爲空
     * @throws IllegalArgumentException 如果指定集合的元素的某些屬性阻止將其添加到此隊列,或者指定的集合是此隊列
     * @throws IllegalStateException 如果由於插入限制,此時不能添加所有元素
     */
    public boolean addAll(Collection<? extends E> c) {
        if (c == null)
            throw new NullPointerException();
        if (c == this)
            throw new IllegalArgumentException();
        boolean modified = false;
        for (E e : c)
          	// 基於add方法
            if (add(e))
                modified = true;
        return modified;
    }
}

3. Deque 接口

/**
 * 支持在兩端插入和移除元素的線性集合。deque是“double ended queue”的縮寫,通常讀作“deck”。
 * 大多數Deque實現對包含的元素的數量沒有固定的限制,
 * 這個接口支持容量受限的deque以及沒有固定大小限制的deque。
 * 
 * 這個接口定義了訪問deque兩端元素的方法。
 * 提供了用於插入、刪除和檢查元素的方法。
 * 這些方法都以兩種形式存在:一種方法在操作失敗時拋出異常,另一種方法返回特殊值(null或false,取決於操作)。
 * 後一種插入操作是專門爲容量受限的Deque實現而設計的;在大多數實現中,插入操作不會失敗。
 *
 * 以上12種方法總結如下表:
 **/

在這裏插入圖片描述

/**
 * 這個接口擴展了Queue接口。當deque用作隊列時,FIFO(先進先出)行爲將產生。
 * 元素添加在deque的末尾,並從開頭刪除。從Queue接口繼承的方法與Deque方法完全等價,如下表所示:
 **/

在這裏插入圖片描述

/**
 * Deques也可以作爲後進先出的堆棧。這個接口應該優先用於遺留Stack類。
 * 當deque用作堆棧時,元素從deque的開頭被推入和彈出。
 * 如下表所示,堆棧方法與Deque方法完全等價:
 **/

在這裏插入圖片描述

/**
 * 注意,當deque被用作隊列或堆棧時,peek方法也同樣有效;在這兩種情況下,元素都是從deque的開頭抽取的。
 *
 * 這個接口提供了兩種方法來刪除內部元素,removeFirstOccurrence和removeLastOccurrence。
 * 
 * 與List接口不同,此接口不支持對元素的索引訪問。
 *
 * 雖然並不嚴格要求Deque實現禁止插入空元素,但強烈建議這樣做。
 * 強烈建議使用任何允許空元素的Deque實現的用戶不要使用其插入空值的能力。
 * 這是因爲null被各種方法用作特殊的返回值,以表明deque是空的。
 *
 * Deque實現通常不定義equals和hashCode方法的基於元素的版本,而是從類對象繼承基於身份的版本。
 *
 * 該接口是Java集合框架的成員。
 */
public interface Deque<E> extends Queue<E> {
    /**
     * 如果不違反容量限制,則在deque的頭部插入指定的元素。
     * 如果當前沒有空間可用,拋出IllegalStateException異常。
     * 當使用容量受限的deque時,通常最好使用方法offerFirst。
     * @param e 要插入的元素
     * @throws IllegalStateException 如果由於容量限制,此時不能添加元素
     * @throws ClassCastException 如果指定元素的類阻止它被添加到此deque
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     * @throws IllegalArgumentException 如果指定元素的某些屬性阻止將其添加到此deque中
     */
    void addFirst(E e);

    /**
     * 如果不違反容量限制,則在deque的尾部插入指定的元素。
     * 如果當前沒有空間可用,拋出IllegalStateException異常。
     * 當使用容量受限的deque時,通常最好使用方法offerLast。
     *
     * 這個方法等同於add方法。
     *
     * @param e 要插入的元素
     * @throws IllegalStateException 如果由於容量限制,此時不能添加元素
     * @throws ClassCastException 如果指定元素的類阻止它被添加到此deque
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     * @throws IllegalArgumentException 如果指定元素的某些屬性阻止將其添加到此deque中
     */
    void addLast(E e);

    /**
     * 如果不違反容量限制,則在deque的頭部插入指定的元素。
     * 當使用容量受限的deque時,此方法通常比addFirst方法更好,後者可能無法插入元素,而只是拋出一個異常。
     *
     * @param e 要插入的元素
     * @throws IllegalStateException 如果由於容量限制,此時不能添加元素
     * @throws ClassCastException 如果指定元素的類阻止它被添加到此deque
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     * @throws IllegalArgumentException 如果指定元素的某些屬性阻止將其添加到此deque中
     */
    boolean offerFirst(E e);

    /**
     * 如果不違反容量限制,則在deque的尾部插入指定的元素。
     * 當使用容量受限的deque時,此方法通常比addLast方法更好,後者可能無法插入元素,而只是拋出一個異常。
     *
     * @param e 要插入的元素
     * @throws IllegalStateException 如果由於容量限制,此時不能添加元素
     * @throws ClassCastException 如果指定元素的類阻止它被添加到此deque
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     * @throws IllegalArgumentException 如果指定元素的某些屬性阻止將其添加到此deque中
     */
    boolean offerLast(E e);

    /**
     * 返回並且移出隊列的第一個元素。這個方法不同於pollFirst只在於,當隊列爲空,本方法拋出異常。
     * @throws NoSuchElementException 如果隊列爲空
     */
    E removeFirst();

    /**
     * 返回並且移出隊列的最後一個元素。這個方法不同於pollLast只在於,當隊列爲空,本方法拋出異常。
     * @throws NoSuchElementException 如果隊列爲空
     */
    E removeLast();

    /**
     * 返回並且移出隊列的第一個元素,當隊列爲空時,返回null
     */
    E pollFirst();

    /**
     * 返回並且移出隊列的最後一個元素,當隊列爲空時,返回null
     */
    E pollLast();

    /**
     * 返回,但不移出隊列的第一個元素。這個方法不同於peekFirst方法只在於,當隊列爲空,本方法拋出異常。
     * @throws NoSuchElementException 如果隊列爲空
     */
    E getFirst();

    /**
     * 返回,但不移出隊列的最後一個元素。這個方法不同於peekLast方法只在於,當隊列爲空,本方法拋出異常。
     * @throws NoSuchElementException 如果隊列爲空
     */
    E getLast();

    /**
     * 返回,但不移出隊列的第一個元素。當隊列爲空,返回null。
     */
    E peekFirst();

    /**
     * 返回,但不移出隊列的最後一個元素。當隊列爲空,返回null。
     */
    E peekLast();

    /**
     * 從deque中移除指定元素的第一個匹配項。如果deque不包含該元素,它將保持不變。
		 * 更正式地說,刪除第一個元素o(如果存在這樣的元素)。
		 * 如果這個deque包含指定的元素,則返回true(或者等價地,如果這個deque因爲調用而改變)。
     *
     * @throws ClassCastException 如果指定元素的類與此deque不兼容
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     */
    boolean removeFirstOccurrence(Object o);

    /**
     * 從deque中移除指定元素的最後一個匹配項。如果deque不包含該元素,它將保持不變。
		 * 更正式地說,刪除最後一個元素o(如果存在這樣的元素)。
		 * 如果這個deque包含指定的元素,則返回true(或者等價地,如果這個deque因爲調用而改變)。
     * @throws ClassCastException 如果指定元素的類與此deque不兼容
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     */
    boolean removeLastOccurrence(Object o);

    // *** Queue methods ***

    /**
     * 這個方法等同於addLast。
     */
    boolean add(E e);

    /**
     * 此方法等同於offerLast
     */
    boolean offer(E e);

    /**
     * 此方法等同於removeFirst
     */
    E remove();

    /**
     * 此方法等同於pollFirst
     */
    E poll();

    /**
     * 此方法等同於getFirst
     */
    E element();

    /**
     * 此方法等同於peekFirst
     */
    E peek();


    // *** Stack methods ***

    /**
     * 此方法等同於addFirst
     */
    void push(E e);

    /**
     * 此方法等同於removeFirst
     */
    E pop();


    // *** Collection methods ***

    /**
     * 從deque中移除指定元素的第一個匹配項。如果deque不包含該元素,則它將保持不變。
     * 更正式地說,刪除第一個元素(如果存在這樣一個元素)。
     * 如果這個deque包含指定的元素,則返回true(或者同樣地,如果這個deque由於調用而改變)。
     *
     * 這個方法相當於removeFirstOccurrence(Object)方法。
     *
     * @throws ClassCastException 如果指定元素的類與此deque不兼容
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     */
    boolean remove(Object o);

    /**
     * 如果該deque包含指定的元素,則返回true。
		 * 更正式地說,當且僅當deque至少包含一個元素o時,返回true
     *
     * @param o 將被測試,是否存在在這個deque中的元素
     * @return 如果這個deque包含指定的元素,則爲true
     * @throws ClassCastException 如果指定元素的類型與此deque不兼容
     * @throws NullPointerException 如果指定的元素爲空,並且deque不允許空元素
     */
    boolean contains(Object o);

    /**
		 * 返回deque中的元素數量。
     */
    public int size();

    /**
     * 按適當的順序返回deque中元素的迭代器。元素將按從第一個(head)到最後一個(tail)的順序返回。
     */
    Iterator<E> iterator();

    /**
     * 以相反的順序返回deque中元素的迭代器。元素將按從最後(尾)到第一個(頭)的順序返回。
     */
    Iterator<E> descendingIterator();

}

下一篇:[集合類]源碼解析7(AbstractSequentialList抽象類和LinkedList類)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章