首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 設計模式:迭代器模式全面掌握

     編輯:Java 相關知識

從日常使用說起

Java 開發者每天都在用迭代器:


Iterator it = list.iterator();
while (it.hasNext()) {
    String item = it.next();
    // 業務邏輯
}

這正是迭代器模式的經典應用——提供統一介面順序存取聚合物件內部元素,而無需暴露其內部結構。

模式定義與四大角色

GoF 定義:提供一種方法訪問容器物件中各個元素,而又不需暴露該物件的內部細節。

角色類別/介面職責
Iterator介面定義 hasNext()、next()、remove() 等遍歷操作
ConcreteIterator類別實現遍歷演算法,維護當前游標位置
Container (Aggregate)介面宣告 iterator() 工廠方法
ConcreteContainer類別實現 iterator() 返回專屬迭代器實例

關鍵設計決策

1. 內部 vs 外部迭代器

類型控制權特點
外部迭代器客戶端靈活、可暫停/恢復、支援多重並發遍歷,Java 採用此模式
內部迭代器迭代器自身簡單但剛性,難以支援嵌套/並發遍歷,Java 中較少見

2. 遍歷演算法放在哪?

  • 迭代器中:演算法可複用於不同容器,但需容器暴露內部結構(破壞封裝)
  • 容器中:保護封裝,但演算法與容器綁定
  • Java 方案:迭代器作為容器的內部類,既能訪問私有欄位,又對外只暴露 Iterator 介面

JDK 內部實現剖析

AbstractList.Itr 為內部類實現:


private class Itr implements Iterator {
    int cursor = 0;           // 下一個元素索引
    int lastRet = -1;         // 上次返回元素索引
    int expectedModCount = modCount; // 快速失效機制
    
    public boolean hasNext() { return cursor != size(); }
    
    public E next() {
        checkForComodification();
        try {
            E next = get(cursor);
            lastRet = cursor++;
            return next;
        } catch (IndexOutOfBoundsException e) {
            checkForComodification();
            throw new NoSuchElementException();
        }
    }
    
    public void remove() {
        if (lastRet == -1) throw new IllegalStateException();
        checkForComodification();
        try {
            AbstractList.this.remove(lastRet);
            if (lastRet < cursor) cursor--;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException e) {
            throw new ConcurrentModificationException();
        }
    }
    
    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

多態迭代的威力

客戶端程式碼只依賴 Iterator 介面,可透明遍歷 ArrayList、LinkedList、HashSet、TreeSet 等任意容器:


public void printAll(Collection coll) {
    for (Iterator it = coll.iterator(); it.hasNext(); ) {
        System.out.println(it.next());
    }
}

自製迭代器的關鍵考量

挑戰解決思路
遍歷過程中修改容器採用快速失效:維護 modCount,檢測並發修改拋出 ConcurrentModificationException
支援深度遍歷(樹/圖)迭代器內部維護堆疊/隊列,實現前序/中序/後序/廣度優先等多種策略
多種遍歷方式共存容器提供多個工廠方法:preOrderIterator()、breadthFirstIterator() 等

Java 8+ 的演進:Spliterator 與 Stream

  • Spliterator:可分割迭代器,支援並行遍歷,是 Stream API 底層基石
  • stream() / parallelStream():宣告式資料處理,內部迭代器,自動並行化
  • 但 Iterator 仍是基礎,Stream 內部仍依賴 Spliterator/Iterator

總結

迭代器模式是容器與演算法解耦的經典範例。它將「如何遍歷」從「儲存什麼」中分離,支援多種遍歷策略並存、同一容器並發多重遍歷、統一介面屏蔽底層結構差異。理解其內部類實現、快速失效機制、多態迭代本質,有助於深入掌握 Java 集合框架與 Stream API 的設計精髓。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved