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

迭代器模式 Java 實現:統一遍歷介面、封裝聚合內部結構

     編輯:Java 相關知識

模式定義與核心價值

迭代器模式提供統一介面順序訪問聚合對象元素,不暴露內部結構 (數組、鏈表、樹、圖...)。核心角色:

  • Iterator (迭代器介面):hasNext()、next()、hasPrevious()、previous()。
  • ConcreteIterator (具體迭代器):維護遍歷狀態 (游標)、實現演算邏輯。
  • Aggregate (聚合介面):iterator() 工廠方法。
  • ConcreteAggregate (具體聚合):實現 iterator() 返回對應迭代器。

自定義集合與迭代器完整實現

1. 聚合介面


public interface ICollection {
    IIterator iterator(); // 工廠方法
    void add(T item);
    T get(int index);
    int size();
}

2. 迭代器介面


public interface IIterator {
    boolean hasNext();
    boolean hasPrevious();
    T next();
    T previous();
}

3. 具體聚合:動態數組實現


public class MyArrayList implements ICollection {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_CAPACITY = 10;
    
    public MyArrayList() { elements = new Object[DEFAULT_CAPACITY]; }
    
    @Override
    public void add(T item) {
        ensureCapacity();
        elements[size++] = item;
    }
    
    @Override
    public T get(int index) { checkIndex(index); return (T) elements[index]; }
    @Override
    public int size() { return size; }
    
    @Override
    public IIterator iterator() {
        return new ArrayIterator<>(this);
    }
    
    private void ensureCapacity() {
        if (size == elements.length) {
            elements = Arrays.copyOf(elements, size * 2);
        }
    }
    private void checkIndex(int i) { if (i < 0 || i >= size) throw new IndexOutOfBoundsException(); }
    
    // 內部類訪問私有字段
    private static class ArrayIterator implements IIterator {
        private final MyArrayList list;
        private int cursor = 0;
        ArrayIterator(MyArrayList list) { this.list = list; }
        
        public boolean hasNext() { return cursor < list.size; }
        public boolean hasPrevious() { return cursor > 0; }
        public T next() { if (!hasNext()) throw new NoSuchElementException(); return list.get(cursor++); }
        public T previous() { if (!hasPrevious()) throw new NoSuchElementException(); return list.get(--cursor); }
    }
}

4. 另一聚合:鏈表實現 (共用同一迭代器介面)


public class MyLinkedList implements ICollection {
    private Node head, tail;
    private int size = 0;
    
    static class Node { T item; Node next, prev; }
    
    public void add(T item) {
        Node node = new Node<>(); node.item = item;
        if (tail == null) head = tail = node;
        else { tail.next = node; node.prev = tail; tail = node; }
        size++;
    }
    
    @Override public T get(int index) { /* 遍歷查找略 */ return null; }
    @Override public int size() { return size; }
    
    @Override
    public IIterator iterator() {
        return new LinkedIterator<>(this);
    }
    
    private static class LinkedIterator implements IIterator {
        private final MyLinkedList list;
        private Node current = list.head;
        LinkedIterator(MyLinkedList list) { this.list = list; }
        
        public boolean hasNext() { return current != null; }
        public boolean hasPrevious() { return current != list.head; }
        public T next() { if (!hasNext()) throw new NoSuchElementException(); T item = current.item; current = current.next; return item; }
        public T previous() { if (!hasPrevious()) throw new NoSuchElementException(); current = current.prev; return current.item; }
    }
}

5. 客戶端統一遍歷


public class IteratorDemo {
    public static void main(String[] args) {
        // 測試動態數組
        ICollection arrayColl = new MyArrayList<>();
        arrayColl.add("A"); arrayColl.add("B"); arrayColl.add("C");
        traverse(arrayColl);
        
        // 測試鏈表
        ICollection linkedColl = new MyLinkedList<>();
        linkedColl.add(1); linkedColl.add(2); linkedColl.add(3);
        traverse(linkedColl);
    }
    
    static  void traverse(ICollection coll) {
        System.out.println("=== 遍歷 " + coll.getClass().getSimpleName() + " ===");
        for (IIterator it = coll.iterator(); it.hasNext(); ) {
            System.out.print(it.next() + " ");
        }
        System.out.println("\n=== 反向遍歷 ===");
        for (IIterator it = coll.iterator(); it.hasPrevious(); ) {
            System.out.print(it.previous() + " ");
        }
        System.out.println("\n");
    }
}

輸出結果

=== 遍歷 MyArrayList ===
A B C 
=== 反向遍歷 ===
C B A 

=== 遍歷 MyLinkedList ===
1 2 3 
=== 反向遍歷 ===
3 2 1 

JDK 內建迭代器模式應用

  • Collection.iterator() 返回 Iterator — 標準角色映射。
  • List.listIterator() 返回 ListIterator — 增強版 (雙向、索引、修改)。
  • Map 無直接迭代器,但 entrySet()、keySet()、values() 返回可迭代視圖。

增強功能:Java 8+ 函數式遍歷


// Iterable 繼承自 Iterable,支援 forEach
coll.forEach(System.out::print); // 內部迭代

// Stream API (內部迭代、並行、管道)
coll.stream().filter(s -> s.length() > 1).map(String::toUpperCase).forEach(System.out::println);

設計模式對比

最佳實踐

  1. 優先用 JDK 集合:ArrayList、LinkedList、HashSet 已完美實現迭代器模式。
  2. 自定義聚合實現 Iterable:直接實現 Iterable,即可支援 for-each 循環。
  3. 迭代器不可變原則:遍歷過程中修改集合拋 ConcurrentModificationException (fail-fast),或用 CopyOnWriteArrayList (weakly consistent)。
  4. 並發環境:ConcurrentHashMap 迭代器弱一致,不拋異常,反映迭代瞬間狀態。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
模式核心意圖關鍵差異
迭代器統一遍歷介面關注「如何遍歷」,封裝遍歷狀態
訪問者分離操作與對象結構關注「做什麼操作」,雙分發
組合樹形結構統一介面關注「部分-整體」層次