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

Java Iterator 迭代器深度解析:用法、原理與最佳實踐

     編輯:Java 相關知識

什麼是迭代器模式?

迭代器 是一種行為型設計模式,提供統一介面順序訪問聚合物件內部元素,而無需暴露其內部結構。Java 中 java.util.Iterator 是此模式的標準實現,被稱為「輕量級」物件,因建立開銷極小。

核心 API

Iterator<E> 介面定義四個方法:

方法回傳值說明
hasNext()boolean是否還有下一個元素
next()E返回下一個元素並移動游標
remove()void移除最後一次 next() 返回的元素(可選操作)
forEachRemaining(Consumer)voidJava 8+,對剩餘元素執行動作

基本用法

標準遍歷模式

List<String> list = new ArrayList<>(Arrays.asList("aa", "bb", "cc"));

// 方式一:for 迴圈
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
    String s = it.next();
    System.out.println(s);
}

// 方式二:while 迴圈
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    System.out.println(s);
}

// 方式三:Java 8+ forEachRemaining
list.iterator().forEachRemaining(System.out::println);

安全移除元素

唯一安全在迭代過程中修改集合的方式:

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if ("bb".equals(s)) {
        it.remove(); // 僅能移除最後 next() 返回的元素
    }
}
// 呼叫 list.remove() 會拋出 ConcurrentModificationException

ListIterator:雙向游標與增強操作

專為 List 設計,繼承 Iterator 並新增:

  • 雙向遍歷:hasPrevious()、previous()、nextIndex()、previousIndex()
  • 修改操作:set(E e) 替換元素、add(E e) 插入元素
ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) {
    int idx = lit.nextIndex();
    String val = lit.next();
    if (idx == 1) {
        lit.set("BB");      // 替換
        lit.add("INSERT");  // 在當前位置前插入
    }
}

底層原理:Fail-Fast 機制

集合內部維護 modCount 修改計數器。迭代器建立時捕獲 expectedModCount = modCount。每次 next()、remove() 先檢查:

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

注意:此機制為「盡力而為」,不保證多執行緒下絕對安全,僅作為程式錯誤偵測輔助。

進階主題

Spliterator:並行流的基石

Java 8 引入 Spliterator,支援分割遍歷,是 Stream API 並行處理的基礎。特性旗標:

  • ORDERED、DISTINCT、SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT、SUBSIZED

自定義迭代器

public class Range implements Iterable<Integer> {
    private final int start, end;
    public Range(int start, int end) { this.start = start; this.end = end; }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<>() {
            int current = start;
            public boolean hasNext() { return current < end; }
            public Integer next() { return current++; }
        };
    }
}

// 使用:for (int i : new Range(0, 10)) { ... }

最佳實踐清單

  1. 優先使用 增強 for 迴圈(for (E e : coll)),編譯器自動轉為迭代器,碼簡潔且安全
  2. 需要移除元素時,必須使用顯式迭代器的 remove()
  3. 多執行緒環境下,使用 Collections.synchronizedList、CopyOnWriteArrayList 或並行流
  4. 實作 Iterable 介面讓自定義類支援 for-each 語法
  5. 避免在迭代中執行耗時操作,導致游標長期持有鎖或資源
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved