java基礎 迭代Iterable接口以及迭代器Iterator

Itera迭代

  • Iterable < T>迭代接口
    • (1) Iterator iterator()
    • (2) forEach(Consumer<? super T> action)
      • forEach結合Consumer常見場景
      • forEach使用注意細節
    • (3)Spliterator spliterator()
  • Iterator< T>迭代器接口
    • 如何“接收” Iterator<T>
    • 核心方法
    • 迭代器的使用場景
    • 注意事項
  • 總結

在 Java 中, Iterable < T> 是一個核心接口,用于表示一個對象可以被 迭代(遍歷),它定義了如何通過 迭代器(Iterator< T>)訪問其元素,并支持增強的 for-each 循環

Iterable < T>迭代接口

public interface Iterable<T> {Iterator<T> iterator(); // 必須實現的方法// Java 8 新增的默認方法default void forEach(Consumer<? super T> action) { /* ... */ }// Java 8 新增的默認方法default Spliterator<T> spliterator() { /* ... */ }
}

(1) Iterator iterator()

作用:返回一個迭代器(Iterator< T>),用于遍歷集合中的元素或進行刪除元素操作。
實現要求:每個 Iterable 實現類必須提供該方法,返回一個新的迭代器實例

(2) forEach(Consumer<? super T> action)

作用:對集合中的每個非空元素進行遍歷

	// 下界通配符 <? super T> 表示“T 或 T 的父類”default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}}

首先,這段代碼里的forEach方法接受一個Consumer(消費者)參數,Consumer是一個函數式接口,接受一個輸入參數并且不返回結果,accept方法為void
其次,這里用了泛型通配符<? super T>,表示Consumer可以處理T類型及其父類,比如有一個Animal的Consumer,而T是Dog,那么也可以接受這個Consumer。

步驟1.首先Objects.requireNonNull,確保傳入的action不是null,避免空指針異常,注意是action判空
步驟2.接下來是一個增強的for循環,遍歷this,也就是當前的Iterable實例
步驟3.每次循環取出元素t,調用action的accept方法處理它,具體如何處理 t,完全由 Consumer 的實現邏輯決定,是具體的消費操作action

forEach結合Consumer常見場景

(1) 示例 1:打印元素

List<String> list = Arrays.asList("A", "B", "C");
list.forEach(element -> System.out.println(element));

forEach方法參數是 str -> System.out.println(str) :是一個 Consumer< String> 的實現,action就是打印元素:每次調用 accept(t) 時,會執行 System.out.println(t),即打印當前元素。

(2) 示例 2:修改對象狀態

List<Person> persons = getPersons();
persons.forEach(person -> person.setAge(18)); // 將所有 Person 的年齡設為 18

邏輯分解:
person -> person.setAge(18) 是 Consumer 的實現。每次調用 accept(t) 時,執行 t.setAge(18),修改元素的狀態。

(3) 示例 3:條件判斷與過濾

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
numbers.forEach(num -> {if (num % 2 == 0) {System.out.println(num + " 是偶數");}
});

在 accept(t) 中,根據 t 的值執行條件判斷,僅處理滿足條件的元素。

(4) 示例 4:方法引用

list.forEach(System.out::println); // 方法引用

等價于:

list.forEach(str -> System.out.println(str));

原理:System.out::println 是 Consumer< String> 的實現,accept(t) 會調用 System.out.println(t)

forEach使用注意細節

①上述的判空處理是判斷集合是否或操作是否為空,不是判斷集合中的某個元素為null
②對于Null的元素,foreach遍歷輸出要看具體的子類處理,如List的遍歷是將其作為 null字符打印處理

        List<String> list = Arrays.asList("A",null, "C");list.forEach(element -> System.out.println(element));

輸出

A
null //字符null 不是空 Null
C

(3)Spliterator spliterator()

Spliterator可拆分迭代器介紹鏈接
流Stream AP介紹點擊鏈接
Spliterator 是 Stream API 并行處理的底層實現,現在的實際工作場景中,應用流對集合進行處理是 非常常見的,代碼使用是非常簡潔的,這兩個單獨拿出來說

Iterator< T>迭代器接口

Iterator 是 Java 集合框架中用于遍歷集合元素的接口,定義如下:

public interface Iterator<T> {boolean hasNext();    // 檢查是否還有下一個元素T next();             // 返回下一個元素void remove();        // 移除當前元素(可選操作)
}

如何“接收” Iterator

(1) 通過集合的 iterator() 方法
有實現了 Iterable 接口的集合類(如 List, Set, Queue)都可通過 iterator() 方法返回迭代器:

List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator(); // 獲取迭代器

(2) 自定義集合類實現 Iterable<T>
若需讓自定義集合支持迭代,需實現 Iterable 并返回自定義的 Iterator

public class MyCollection<T> implements Iterable<T> {private List<T> elements = new ArrayList<>();public void add(T element) {elements.add(element);}@Overridepublic Iterator<T> iterator() {return new MyIterator(); // 返回自定義迭代器}// 自定義迭代器實現private class MyIterator implements Iterator<T> {private int index = 0;@Overridepublic boolean hasNext() {return index < elements.size();}@Overridepublic T next() {if (!hasNext()) throw new NoSuchElementException();return elements.get(index++);}@Overridepublic void remove() {elements.remove(--index);}}
}

核心方法

(1) boolean hasNext()
作用:判斷集合中是否還有未被遍歷的元素。
返回值:
true:存在下一個元素。
false:已遍歷完所有元素。

List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> it = list.iterator();
while (it.hasNext()) { // 檢查是否還有元素String element = it.next();System.out.println(element);
}

(2) T next()
作用:返回當前指向的元素,并將迭代器位置后移。
注意事項:
調用前必須檢查 hasNext(),否則可能拋出 NoSuchElementException
返回類型為泛型 T,確保類型安全

Iterator<Integer> it = List.of(1, 2, 3).iterator();
if (it.hasNext()) {int num = it.next(); // 返回 1,迭代器指向下一個元素
}

(3) void remove()
作用:移除迭代器最后一次通過 next() 返回的元素。
注意事項:
必須在 next() 之后調用,否則拋出 IllegalStateException
不是所有迭代器都支持此操作,如ArrayList的迭代器執行此操作,不支持刪除操作的迭代器如Collections.unmodifiableList()返回的迭代器,調用前需檢查是否實現(默認可能拋出 UnsupportedOperationException)。

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> it = list.iterator();
while (it.hasNext()) {String element = it.next();if (element.equals("B")) {it.remove(); // 移除 "B"}
}
System.out.println(list); // 輸出 [A, C]

(4) forEachRemaining(Consumer<? super E> action)
上面三個方法是迭代器的核心方法,這個方法是將上面三個方法集合在一起了,他是對父接口的for-each方法的一種補充

    default void forEachRemaining(Consumer<? super E> action) {Objects.requireNonNull(action);while (hasNext())action.accept(next());}

和for-each區別就在于,for-each會將集合中的全部元素按照執行操作執行一遍,forEachRemaining則是將剩余未處理的元素按照執行操作執行一遍,配合可拆分迭代器spliterator中使用樣例

List<String> list = Arrays.asList("Java", "Python", "C++", "Go");
Spliterator<String> spliterator = list.spliterator();// 處理前兩個元素
spliterator.tryAdvance(System.out::println); // Java
spliterator.tryAdvance(System.out::println); // Python// 這時候還剩余兩個元素 批量處理剩余元素 
spliterator.forEachRemaining(System.out::println); // 輸出:
// C++
// Go

迭代器的使用場景

(1) 遍歷集合并修改元素

List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3));
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {int num = it.next();if (num % 2 == 0) {it.remove(); // 安全刪除偶數}
}

(2) 遍歷不可索引的集合(如 Set)

Set<String> names = new HashSet<>(Set.of("Alice", "Bob"));
Iterator<String> it = names.iterator();
while (it.hasNext()) {System.out.println(it.next());
}

(3) 結合流式處理(Stream API)
這種方式也是實際工作中常見的

List<String> list = List.of("Java", "Python", "C++");
list.stream().filter(s -> s.startsWith("J")).forEach(System.out::println); // 輸出 "Java"

注意事項

①迭代器的三個方法執行有先后順序
boolean hasNext(); // 檢查是否還有下一個元素
T next(); // 返回下一個元素
void remove(); // 移除當前元素(可選操作)
hasNext() 先保證還有下一個元素 ===》next()指針才做指向下一個元素返回---》指向返回元素才能進行操作元素 remove();刪除

②單次遍歷:一個迭代器只能遍歷集合一次,遍歷結束后需重新獲取迭代器。不可重復使用迭代器 即每次調用 iterator() 應返回一個新的迭代器實例。

③并發修改

List<String> list = new ArrayList<>(Arrays.asList("A", "B"));
Iterator<String> it = list.iterator();
list.add("C"); // 直接修改集合
it.next();     // 拋出 ConcurrentModificationException

解決方案:使用并發集合(如 CopyOnWriteArrayList)或在迭代期間僅通過迭代器修改集合

總結

1.迭代Iterable接口和迭代器Iterator接口 聯系與區別
①關聯:Iterable接口主要生成迭代器和增強for each循環,而增強的 for-each 循環底層依賴 Iterator,無論是在集合還是數組上使用 for-each 循環,其內部都會轉換為相應的迭代器操作,具體的實現方式需要去查看迭代接口的實現類,如ArrayList

//增強for each循環
for (String s : list) {System.out.println(s);
}
//等價于:
Iterator<String> it = list.iterator();
while (it.hasNext()) {String s = it.next();System.out.println(s);
}

②區別:除此之外迭代器提供了一種更為安全的刪除元素的操作方式,即迭代器的三個關鍵方法:hasNext(), next(), remove()配合使用,當僅僅需要遍歷集合使用for-each就可以,但如果需要刪除元素時,可以使用迭代器的 remove() 方法,兩者的主要區別

Iterable<T>Iterator<T>
表示對象可被迭代實際執行迭代操作
定義 iterator() 方法定義 hasNext(), next(), remove()
支持 for-each 循環手動控制遍歷過程

2.集合框架中幾乎所有集合類都實現了 Iterable,例如

  • List(如 ArrayList, LinkedList)
  • Set(如 HashSet, TreeSet)
  • Queue(如 PriorityQueue)

表名這些集合類都是可以被迭代的,當然也都都可以使用迭代器

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/76053.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/76053.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/76053.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PyTorch構建自定義模型

PyTorch 提供了靈活的方式來構建自定義神經網絡模型。下面我將詳細介紹從基礎到高級的自定義模型構建方法&#xff0c;包含實際代碼示例和最佳實踐。 一、基礎模型構建 1. 繼承 nn.Module 基類 所有自定義模型都應該繼承 torch.nn.Module 類&#xff0c;并實現兩個基本方法&…

AI智算-K8s如何利用GPFS分布式并行文件存儲加速訓練or推理

文章目錄 GPFS簡介核心特性存儲環境介紹存儲軟件版本客戶端存儲RoCEGPFS 管理(GUI)1. 創建 CSI 用戶2. 檢查GUI與k8s通信文件系統配置1. 開啟配額2. 啟用filesetdf文件系統3. 驗證文件系統配置4. 啟用自動inode擴展存儲集群配置1. 啟用對根文件集(root fileset)配額2. igno…

gbase8s之邏輯導出導入腳本(完美版本)

該腳本dbexport.sh用于快速導出庫和導入庫&#xff08;使用多并發unload&#xff0c;和多并發dbload的方式&#xff09; #!/bin/sh #腳本功能&#xff1a;將數據導出成文本&#xff0c;遷移至其他實例 #最后更新時間&#xff1a;2023-12-19 #使用方法&#xff1a; #1.執行該腳…

springMVC-攔截器詳解

攔截器 概述 SpringMVC的處理器攔截器類似于Servlet開發中的過濾器Filter,用于對處理器進行預處理和后處理。開發者可以自己定義一些攔截器來實現特定的功能。 過濾器與攔截器的區別&#xff1a;攔截器是AOP思想的具體應用。 過濾器 servlet規范中的一部分&#xff0c;任何ja…

網絡安全應急響應-系統排查

在網絡安全應急響應中&#xff0c;系統排查是快速識別潛在威脅的關鍵步驟。以下是針對Windows和Linux系統的系統基本信息排查指南&#xff0c;涵蓋常用命令及注意事項&#xff1a; 一、Windows系統排查 1. 系統信息工具&#xff08;msinfo32.exe&#xff09; 命令執行&#x…

基于YOLO的半自動化標注方法:提升鐵路視頻缺陷檢測效率

論文地址:https://arxiv.org/pdf/2504.01010 1. 論文結構概述 本文提出了一種半自動化標注方法,旨在解決鐵路缺陷檢測中大規模圖像/視頻數據集標注成本高、耗時長的問題。論文結構清晰,分為以下核心部分: ?引言(Introduction)? 強調傳統手動標注的痛點(耗時、易錯、…

Linux驅動開發:SPI驅動開發原理

前言 本文章是根據韋東山老師的教學視頻整理的學習筆記https://video.100ask.net/page/1712503 SPI 通信協議采用同步全雙工傳輸機制&#xff0c;拓撲架構支持一主多從連接模式&#xff0c;這種模式在實際應用場景中頗為高效。其有效傳輸距離大致為 10m &#xff0c;傳輸速率…

Android Hilt 教程

Android Hilt 教程 —— 一看就懂&#xff0c;一學就會 1. 什么是 Hilt&#xff1f;為什么要用 Hilt&#xff1f; Hilt 是 Android 官方推薦的 依賴注入&#xff08;DI&#xff09;框架&#xff0c;基于 Dagger 開發&#xff0c;能夠大大簡化依賴注入的使用。 為什么要用 Hi…

【算法手記11】NC41 最長無重復子數組 NC379 重排字符串

&#x1f984;個人主頁:修修修也 &#x1f38f;所屬專欄:刷題 ??操作環境:牛客網 目錄 一.NC41 最長無重復子數組 題目詳情: 題目思路: 解題代碼: 二.NC379 重排字符串 題目詳情: 題目思路: 解題代碼: 結語 一.NC41 最長無重復子數組 牛客網題目鏈接(點擊即可跳轉):NC41 最長…

C語言:字符串處理函數strstr分析

在 C 語言中&#xff0c;strstr 函數用于查找一個字符串中是否存在另一個字符串。它的主要功能是搜索指定的子字符串&#xff0c;并返回該子字符串在目標字符串中第一次出現的位置的指針。如果沒有找到子字符串&#xff0c;則返回 NULL。 詳細說明&#xff1a; 頭文件&#xf…

在windows下安裝spark

在windows下安裝spark完成 安裝過程&#xff1a;

MongoDB常見面試題總結(上)

MongoDB 基礎 MongoDB 是什么&#xff1f; MongoDB 是一個基于 分布式文件存儲 的開源 NoSQL 數據庫系統&#xff0c;由 C 編寫的。MongoDB 提供了 面向文檔 的存儲方式&#xff0c;操作起來比較簡單和容易&#xff0c;支持“無模式”的數據建模&#xff0c;可以存儲比較復雜…

【Java設計模式】第2章 UML急速入門

2-1 本章導航 UML類圖與時序圖入門 UML定義 統一建模語言(Unified Modeling Language):第三代非專利建模語言。特點:開放方法,支持可視化構建面向對象系統,涵蓋模型、流程、代碼等。UML分類(2.2版本) 結構式圖形:系統靜態建模(類圖、對象圖、包圖)。行為式圖形:事…

【4】搭建k8s集群系列(二進制部署)之安裝master節點組件(kube-apiserver)

一、下載k8s二進制文件 下載地址&#xff1a; https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG -1.20.md 注&#xff1a;打開鏈接你會發現里面有很多包&#xff0c;下載一個 server 包就夠了&#xff0c;包含了 Master 和 Worker Node 二進制文件。…

電子電氣架構 --- AUTOSAR 的信息安全架構

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 周末洗了一個澡,換了一身衣服,出了門卻不知道去哪兒,不知道去找誰,漫無目的走著,大概這就是成年人最深的孤獨吧! 舊人不知我近況,新人不知我過…

ROS2與OpenAI Gym集成指南:從安裝到自定義環境與強化學習訓練

1.理解 ROS2 和 OpenAI Gym 的基本概念 ROS2&#xff08;Robot Operating System 2&#xff09;&#xff1a;是一個用于機器人軟件開發的框架。它提供了一系列的工具、庫和通信機制&#xff0c;方便開發者構建復雜的機器人應用程序。例如&#xff0c;ROS2 可以處理機器人不同組…

【設計模式】創建型 -- 單例模式 (c++實現)

文章目錄 單例模式使用場景c實現靜態局部變量餓漢式&#xff08;線程安全&#xff09;懶漢式&#xff08;線程安全&#xff09;懶漢式&#xff08;線程安全&#xff09; 智能指針懶漢式(線程安全)智能指針call_once懶漢式(線程安全)智能指針call_onceCRTP 單例模式 單例模式是…

C語言之九九乘法表

一、代碼展示 二、運行結果 三、代碼分析 首先->是外層循環是小于等于9的 然后->是內層循環是小于等于外層循環的 最后->就是\n讓九九乘法表的格式更加美觀(當然 電腦不同 有可能%2d 也有可能%3d) 四、與以下素數題目邏輯相似 五、運行結果

自動化備份全網服務器數據平臺

自動化備份全網服務器數據平臺 項目背景知識 總體需求 某企業里有一臺Web服務器&#xff0c;里面的數據很重要&#xff0c;但是如果硬盤壞了數據就會丟失&#xff0c;現在領導要求把數據做備份&#xff0c;這樣Web服務器數據丟失在可以進行恢復。要求如下&#xff1a;1.每天0…

stm32+esp8266+機智云手機app

現在很多大學嵌入式畢設都要求云端控制&#xff0c;本文章就教一下大家如何使用esp8266去連接機智云的app去進行顯示stm32的外設傳感器數據啊&#xff0c;控制一些外設啊等。 因為本文章主要教大家如何移植機智云的代碼到自己的工程&#xff0c;所以前面的一些準備工作&#x…