欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?迭代器Iterator完整示例解析

 更新時(shí)間:2025年09月17日 09:26:48   作者:祈禱蒼天賜我java之術(shù)  
迭代器(Iterator)是Java集合框架中的一個(gè)核心接口,位于java.util包下,本文給大家講解Java迭代器Iterator完整示例,感興趣的朋友跟隨小編一起看看吧

一、迭代器的基本概念

迭代器(Iterator)是 Java 集合框架中的一個(gè)核心接口,位于 java.util 包下。它定義了一種標(biāo)準(zhǔn)的元素訪(fǎng)問(wèn)機(jī)制,為各種集合類(lèi)型(如 List、Set、Queue 等)提供了一種統(tǒng)一的遍歷方式。

詳細(xì)說(shuō)明

  • 基本功能
    • hasNext():檢查集合中是否還有未遍歷的元素
    • next():返回集合中的下一個(gè)元素
    • remove():從集合中移除當(dāng)前元素(可選操作)
  • 設(shè)計(jì)目的
    • 提供統(tǒng)一的遍歷接口,屏蔽不同集合的內(nèi)部實(shí)現(xiàn)差異
    • 支持安全的并發(fā)修改(fail-fast 機(jī)制)
    • 實(shí)現(xiàn)"惰性求值",只在需要時(shí)才獲取元素
  • 典型使用場(chǎng)景
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> it = list.iterator();
while(it.hasNext()) {
    String element = it.next();
    System.out.println(element);
}
  • 與其他遍歷方式的對(duì)比
    • 比傳統(tǒng)的 for 循環(huán)更安全(避免下標(biāo)越界)
    • 比增強(qiáng) for 循環(huán)更靈活(支持 remove 操作)
    • 適用于所有實(shí)現(xiàn) Iterable 接口的集合類(lèi)
  • 注意事項(xiàng)
    • 不能保證遍歷順序(具體取決于集合實(shí)現(xiàn))
    • 大部分情況下不支持并發(fā)修改
    • 使用后通常會(huì)成為"失效"狀態(tài)
  • 擴(kuò)展機(jī)制
    • ListIterator:針對(duì) List 的增強(qiáng)迭代器,支持雙向遍歷和修改操作
    • Spliterator:Java 8 引入的并行遍歷迭代器

迭代器模式是設(shè)計(jì)模式中行為型模式的一種典型實(shí)現(xiàn),體現(xiàn)了"單一職責(zé)"和"開(kāi)閉原則"的設(shè)計(jì)思想。

二、迭代器的獲取方式

在 Java 集合框架中,所有實(shí)現(xiàn)了 java.util.Collection 接口的集合類(lèi)都提供了 iterator() 方法。這個(gè)方法返回一個(gè)實(shí)現(xiàn)了 java.util.Iterator 接口的迭代器對(duì)象,用于遍歷集合中的元素。這種設(shè)計(jì)模式遵循了迭代器模式(Iterator Pattern),將集合的遍歷操作與集合的具體實(shí)現(xiàn)分離,提供了一種統(tǒng)一的方式來(lái)訪(fǎng)問(wèn)各種不同類(lèi)型的集合。

Iterator 接口定義了三個(gè)核心方法:

  1. hasNext():判斷集合中是否還有下一個(gè)元素
  2. next():返回集合中的下一個(gè)元素
  3. remove():從集合中移除當(dāng)前元素(可選操作)

下面是一個(gè)更詳細(xì)的獲取和使用迭代器的示例代碼,展示了完整的迭代過(guò)程:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo {
    public static void main(String[] args) {
        // 創(chuàng)建一個(gè)ArrayList集合(ArrayList是Collection接口的實(shí)現(xiàn)類(lèi))
        Collection<String> collection = new ArrayList<>();
        // 向集合中添加元素
        collection.add("張三");
        collection.add("李四");
        collection.add("王五");
        collection.add("趙六");
        // 獲取該集合的迭代器對(duì)象
        Iterator<String> iterator = collection.iterator();
        // 使用while循環(huán)遍歷集合元素
        System.out.println("集合中的元素有:");
        while(iterator.hasNext()) {
            // 獲取當(dāng)前元素
            String element = iterator.next();
            System.out.println(element);
            // 示例:移除特定元素
            if(element.equals("李四")) {
                iterator.remove();  // 安全地移除當(dāng)前元素
            }
        }
        // 查看移除后的集合
        System.out.println("\n移除'李四'后的集合:");
        iterator = collection.iterator();  // 重新獲取迭代器
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

在實(shí)際開(kāi)發(fā)中,迭代器常用于以下場(chǎng)景:

  1. 需要邊遍歷邊刪除集合元素時(shí)(使用for-each循環(huán)會(huì)拋出ConcurrentModificationException)
  2. 需要訪(fǎng)問(wèn)某些特殊集合(如ConcurrentHashMap的視圖集合)時(shí)
  3. 需要統(tǒng)一處理不同類(lèi)型集合的遍歷邏輯時(shí)

需要注意的是,迭代器是單向的,一旦遍歷完成就不能重置,如果需要重新遍歷,必須重新獲取迭代器對(duì)象。此外,多個(gè)迭代器可以同時(shí)操作同一個(gè)集合,它們之間互不影響。

三、迭代器的基礎(chǔ)操作

1. hasNext() 方法

hasNext()方法用于判斷集合中是否還有下一個(gè)元素可供訪(fǎng)問(wèn),其返回值為boolean類(lèi)型。該方法不會(huì)移動(dòng)迭代器的指針位置,只是檢查當(dāng)前位置之后是否還有元素存在。

  • 返回true的情況:當(dāng)集合中還有未被遍歷的元素時(shí)
  • 返回false的情況:當(dāng)?shù)饕呀?jīng)到達(dá)集合末尾時(shí)
  • 典型使用場(chǎng)景:作為while循環(huán)的條件,實(shí)現(xiàn)安全遍歷
// 示例:檢查集合是否為空
List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();
if(!it.hasNext()) {
    System.out.println("集合為空");
}

2. next() 方法

next()方法用于獲取集合中的下一個(gè)元素。該方法會(huì)執(zhí)行兩個(gè)操作:

  1. 將迭代器的指針向后移動(dòng)一位
  2. 返回當(dāng)前指針?biāo)赶虻脑?/li>

注意事項(xiàng)

  • 必須先用hasNext()檢查,否則當(dāng)集合中沒(méi)有更多元素時(shí)會(huì)拋出NoSuchElementException
  • 每次調(diào)用都會(huì)移動(dòng)指針位置
  • 返回的是Object類(lèi)型,通常需要強(qiáng)制類(lèi)型轉(zhuǎn)換
// 示例:安全使用next()
List<Integer> numbers = Arrays.asList(1, 2, 3);
Iterator<Integer> iterator = numbers.iterator();
while(iterator.hasNext()) {
    Integer num = iterator.next();  // 自動(dòng)拆箱
    System.out.println(num * 2);  // 輸出2,4,6
}

3. remove() 方法

remove()方法用于刪除迭代器當(dāng)前所指向的元素,即上一次調(diào)用next()方法返回的元素。

方法約束

  1. 必須先調(diào)用next()獲取元素后才能調(diào)用remove()
  2. 每次next()后只能調(diào)用一次remove()
  3. 不能獨(dú)立調(diào)用remove()(即不能連續(xù)調(diào)用兩次remove())
  4. 會(huì)直接修改底層集合的結(jié)構(gòu)

使用場(chǎng)景

  • 安全地刪除集合元素
  • 在遍歷過(guò)程中動(dòng)態(tài)修改集合
// 示例:刪除特定元素
List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
Iterator<String> it = names.iterator();
while(it.hasNext()) {
    String name = it.next();
    if(name.startsWith("A")) {
        it.remove();  // 安全刪除以A開(kāi)頭的元素
    }
}

完整示例解析

下面是更詳細(xì)的示例代碼,展示了迭代器的完整使用流程:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class IteratorOperationDemo {
    public static void main(String[] args) {
        // 創(chuàng)建并初始化集合
        Collection<String> collection = new ArrayList<>();
        collection.add("張三");
        collection.add("李四");
        collection.add("王五");
        collection.add("趙六");
        // 獲取迭代器實(shí)例
        Iterator<String> iterator = collection.iterator();
        // 安全遍歷集合
        try {
            while (iterator.hasNext()) {
                String name = iterator.next();
                System.out.println("當(dāng)前元素: " + name);
                // 條件刪除
                if ("李四".equals(name)) {
                    iterator.remove();
                    System.out.println("已刪除元素: 李四");
                }
            }
        } catch (NoSuchElementException e) {
            System.err.println("錯(cuò)誤: 嘗試訪(fǎng)問(wèn)不存在的元素");
        } catch (IllegalStateException e) {
            System.err.println("錯(cuò)誤: remove()調(diào)用不當(dāng)");
        }
        // 輸出修改后的集合
        System.out.println("\n刪除后的集合內(nèi)容:");
        iterator = collection.iterator();  // 重新獲取迭代器
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        // 驗(yàn)證集合大小
        System.out.println("\n最終集合大小: " + collection.size());
    }
}

輸出結(jié)果分析

當(dāng)前元素: 張三
當(dāng)前元素: 李四
已刪除元素: 李四
當(dāng)前元素: 王五
當(dāng)前元素: 趙六

刪除后的集合內(nèi)容:
張三
王五
趙六

最終集合大小: 3

最佳實(shí)踐建議

使用增強(qiáng)for循環(huán)替代簡(jiǎn)單迭代:Java 5+可以使用增強(qiáng)for循環(huán)簡(jiǎn)化遍歷

for(String name : collection) {
    System.out.println(name);
}
  • 并發(fā)修改問(wèn)題:不要在迭代過(guò)程中直接通過(guò)集合方法修改集合結(jié)構(gòu)(如add/remove),這會(huì)導(dǎo)致ConcurrentModificationException
  • 多線(xiàn)程環(huán)境:在并發(fā)環(huán)境下,應(yīng)考慮使用ConcurrentHashMapCopyOnWriteArrayList等線(xiàn)程安全集合
  • 資源管理:對(duì)于大型集合,迭代完成后可以顯式地將迭代器置為null以幫助垃圾回收
  • 性能考慮:對(duì)于ArrayList,使用索引的for循環(huán)通常比迭代器更快;但對(duì)于LinkedList,迭代器性能更好

四、迭代器的注意事項(xiàng)

在使用迭代器的過(guò)程中,有一些注意事項(xiàng)需要我們特別關(guān)注,否則可能會(huì)導(dǎo)致程序出現(xiàn)異?;虿环项A(yù)期的結(jié)果。這些注意事項(xiàng)在實(shí)際開(kāi)發(fā)中尤為重要,特別是在處理大數(shù)據(jù)集合或多線(xiàn)程環(huán)境下。

1.并發(fā)修改異常(ConcurrentModificationException)

當(dāng)我們使用迭代器遍歷集合時(shí),如果在迭代過(guò)程中通過(guò)集合本身的方法(而不是迭代器的remove()方法)修改了集合的結(jié)構(gòu)(如添加、刪除元素),則會(huì)拋出ConcurrentModificationException異常。這個(gè)異常是Java集合框架設(shè)計(jì)的fail-fast機(jī)制的體現(xiàn)。

具體來(lái)說(shuō),迭代器在創(chuàng)建時(shí)會(huì)記錄集合的modCount(修改次數(shù)),每次對(duì)集合進(jìn)行結(jié)構(gòu)性修改(如add、remove等操作)時(shí),modCount都會(huì)遞增。在迭代過(guò)程中,迭代器會(huì)檢查當(dāng)前modCount是否與創(chuàng)建時(shí)記錄的expectedModCount一致,如果不一致,就會(huì)拋出該異常。

下面是一個(gè)會(huì)拋出ConcurrentModificationException異常的典型示例代碼:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class ConcurrentModificationDemo {
    public static void main(String[] args) {
        Collection<String> collection = new ArrayList<>();
        collection.add("張三");
        collection.add("李四");
        collection.add("王五");
        Iterator<String> iterator = collection.iterator();
        while (iterator.hasNext()) {
            String name = iterator.next();
            System.out.println(name);
            // 通過(guò)集合的add方法添加元素,會(huì)導(dǎo)致ConcurrentModificationException異常
            if ("李四".equals(name)) {
                collection.add("趙六");  // 這里會(huì)拋出異常
            }
        }
    }
}

運(yùn)行上述代碼,程序會(huì)在遍歷到"李四"并嘗試添加"趙六"時(shí)拋出ConcurrentModificationException異常。這種情況常見(jiàn)于以下場(chǎng)景:

  • 在foreach循環(huán)中嘗試修改集合
  • 在多線(xiàn)程環(huán)境下一個(gè)線(xiàn)程迭代而另一個(gè)線(xiàn)程修改集合

為了避免出現(xiàn)這種異常,在迭代過(guò)程中如果需要修改集合的結(jié)構(gòu),應(yīng)該使用迭代器提供的remove()方法:

// 正確的修改方式
iterator.remove();  // 使用迭代器的remove方法

2.迭代器的單向性

Java中的迭代器是單向的,即只能從集合的開(kāi)頭向結(jié)尾遍歷,不能反向遍歷。這種設(shè)計(jì)主要是為了保持接口的簡(jiǎn)潔性和通用性。如果需要進(jìn)行反向遍歷,可以使用ListIterator(僅List接口的實(shí)現(xiàn)類(lèi)支持),ListIterator繼承了Iterator接口,并增加了反向遍歷的相關(guān)方法,如hasPrevious()和previous()等。

ListIterator的主要特點(diǎn)包括:

  • 支持雙向遍歷
  • 允許在迭代過(guò)程中修改集合
  • 可以獲取當(dāng)前元素的位置
  • 可以在迭代過(guò)程中添加元素

下面是一個(gè)使用ListIterator進(jìn)行反向遍歷的完整示例代碼:

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("張三");
        list.add("李四");
        list.add("王五");
        // 獲取ListIterator
        ListIterator<String> listIterator = list.listIterator();
        // 先正向遍歷到末尾
        System.out.println("正向遍歷結(jié)果:");
        while (listIterator.hasNext()) {
            String name = listIterator.next();
            System.out.println(name);
        }
        // 反向遍歷
        System.out.println("\n反向遍歷結(jié)果:");
        while (listIterator.hasPrevious()) {
            String name = listIterator.previous();
            System.out.println(name);
        }
        // 在迭代過(guò)程中添加元素
        while (listIterator.hasNext()) {
            String name = listIterator.next();
            if ("李四".equals(name)) {
                listIterator.add("趙六");  // 在"李四"后面添加新元素
            }
        }
        System.out.println("\n修改后的列表:" + list);
    }
}

運(yùn)行上述代碼,輸出結(jié)果為:

正向遍歷結(jié)果:
張三
李四
王五

反向遍歷結(jié)果:
王五
李四
張三

修改后的列表:[張三, 李四, 趙六, 王五]

3.迭代器的失效

當(dāng)集合的結(jié)構(gòu)發(fā)生改變時(shí)(如使用集合的add()、remove()等方法),之前獲取的迭代器可能會(huì)失效,繼續(xù)使用該迭代器可能會(huì)出現(xiàn)不可預(yù)期的結(jié)果或拋出異常。這種情況在以下場(chǎng)景中特別常見(jiàn):

  • 在多線(xiàn)程環(huán)境中共享集合
  • 在長(zhǎng)時(shí)間運(yùn)行的迭代過(guò)程中
  • 在嵌套迭代時(shí)

因此,當(dāng)集合的結(jié)構(gòu)發(fā)生改變后,最佳實(shí)踐是重新獲取迭代器。例如:

List<String> list = new ArrayList<>();
// ...添加元素...
Iterator<String> iter1 = list.iterator();
// 修改集合結(jié)構(gòu)
list.add("新元素");
// 舊的迭代器可能失效,應(yīng)該重新獲取
Iterator<String> iter2 = list.iterator();  // 獲取新的迭代器

4.對(duì)于不同集合的迭代器實(shí)現(xiàn)

不同的集合類(lèi)對(duì)迭代器接口的實(shí)現(xiàn)可能有所不同,因此在使用迭代器遍歷不同的集合時(shí),其性能和行為可能會(huì)存在顯著差異。

以下是一些常見(jiàn)集合類(lèi)的迭代器特點(diǎn)比較:

集合類(lèi)型迭代器特點(diǎn)適用場(chǎng)景
ArrayList基于數(shù)組實(shí)現(xiàn),next()方法效率高(O(1)),但插入刪除操作會(huì)導(dǎo)致數(shù)組復(fù)制隨機(jī)訪(fǎng)問(wèn)頻繁,修改操作少
LinkedList基于鏈表實(shí)現(xiàn),next()需要移動(dòng)指針(O(n)),但插入刪除效率高(O(1))頻繁插入刪除操作
HashSet基于哈希表實(shí)現(xiàn),迭代順序不確定快速查找,不關(guān)心順序
TreeSet基于紅黑樹(shù)實(shí)現(xiàn),迭代順序是有序的需要有序遍歷
ConcurrentHashMap弱一致性的迭代器,線(xiàn)程安全多線(xiàn)程環(huán)境

選擇集合類(lèi)型時(shí)的建議:

  1. 如果需要頻繁隨機(jī)訪(fǎng)問(wèn),選擇ArrayList
  2. 如果需要頻繁插入刪除,選擇LinkedList
  3. 多線(xiàn)程環(huán)境下考慮并發(fā)集合類(lèi)
  4. 大數(shù)據(jù)量時(shí)考慮迭代器的性能差異

例如,在遍歷LinkedList時(shí),使用普通for循環(huán)的性能會(huì)很差:

// 性能差的方式(LinkedList)
for (int i = 0; i < linkedList.size(); i++) {
    String s = linkedList.get(i);  // 每次get(i)都需要從頭遍歷
}
// 推薦的方式(使用迭代器)
Iterator<String> iter = linkedList.iterator();
while (iter.hasNext()) {
    String s = iter.next();  // 只需移動(dòng)指針
}

理解這些差異有助于我們?cè)趯?shí)際開(kāi)發(fā)中選擇合適的集合類(lèi)型和遍歷方式,從而提高程序性能。

到此這篇關(guān)于Java 迭代器Iterator完整示例解析的文章就介紹到這了,更多相關(guān)Java 迭代器Iterator內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的事件處理機(jī)制詳解

    Java中的事件處理機(jī)制詳解

    這篇文章主要介紹了Java中的事件處理機(jī)制詳解,Java事件處理是采取"委派事件模型",當(dāng)事件發(fā)生時(shí),產(chǎn)生事件的對(duì)象,會(huì)把此"信息"傳遞給"事件的監(jiān)聽(tīng)者"處理,這里所說(shuō)的"信息"實(shí)際上就是java.awt.event事件類(lèi)庫(kù)里某個(gè)類(lèi)創(chuàng)建對(duì)象,需要的朋友可以參考下
    2023-09-09
  • java日期格式化SimpleDateFormat的使用詳解

    java日期格式化SimpleDateFormat的使用詳解

    這篇文章主要介紹了java SimpleDateFormat使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Java遞歸算法遍歷部門(mén)代碼示例

    Java遞歸算法遍歷部門(mén)代碼示例

    這篇文章主要介紹了Java遞歸算法遍歷部門(mén)代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Spring?Boot與Redis的緩存一致性問(wèn)題解決

    Spring?Boot與Redis的緩存一致性問(wèn)題解決

    在使用緩存時(shí),緩存一致性問(wèn)題是一個(gè)常見(jiàn)的挑戰(zhàn),本文主要介紹了Spring?Boot與Redis的緩存一致性問(wèn)題,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • 使用springboot對(duì)外部靜態(tài)資源文件的處理操作

    使用springboot對(duì)外部靜態(tài)資源文件的處理操作

    這篇文章主要介紹了使用springboot對(duì)外部靜態(tài)資源文件的處理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java如何分析算法的時(shí)間和空間復(fù)雜度

    Java如何分析算法的時(shí)間和空間復(fù)雜度

    這篇文章主要介紹了Java如何分析算法的時(shí)間和空間復(fù)雜度,在計(jì)算機(jī)科學(xué)中,計(jì)算復(fù)雜性解釋了算法的性能。文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-06-06
  • 詳解Java信號(hào)量Semaphore的原理及使用

    詳解Java信號(hào)量Semaphore的原理及使用

    Semaphore來(lái)自于JDK1.5的JUC包,直譯過(guò)來(lái)就是信號(hào)量,被作為一種多線(xiàn)程并發(fā)控制工具來(lái)使用。本文將詳解其原理與使用方法,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • Java實(shí)現(xiàn)撲克牌洗牌和發(fā)牌

    Java實(shí)現(xiàn)撲克牌洗牌和發(fā)牌

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)撲克牌洗牌和發(fā)牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 剖析Spring WebFlux反應(yīng)式編程設(shè)計(jì)及工作原理

    剖析Spring WebFlux反應(yīng)式編程設(shè)計(jì)及工作原理

    這篇文章主要為大家介紹了Spring WebFlux反應(yīng)式編程模型工作原理的剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-02-02
  • Spring中IoC優(yōu)點(diǎn)與缺點(diǎn)解析

    Spring中IoC優(yōu)點(diǎn)與缺點(diǎn)解析

    這篇文章主要為大家詳細(xì)解析了Spring中IoC優(yōu)點(diǎn)與缺點(diǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11

最新評(píng)論