Java設(shè)計模式---迭代器模式(Iterator)解讀
迭代器(Iterator)是一種常見的設(shè)計模式,它提供了一種統(tǒng)一的訪問集合元素的方式,同時隱藏了集合的內(nèi)部實現(xiàn)細節(jié)。
注意??:藍色為繼承、黃色為接口實現(xiàn)。

由上圖可知:
- 1、 在集合的頂端為Iterable接口。
- 2、對于AbstractList<E> extends AbstractCollection<E>,兩者均屬于抽象類分別實現(xiàn)List接口和Collection接口。而List接口繼承于Collection接口。
- 3、關(guān)于其他子實現(xiàn)均實現(xiàn)AbstractList,AbstractCollection。
- 4、對于queue接口。和List一樣,繼承Collection接口。
1、迭代器(Iterator)
迭代器是一種對象,它允許你按順序訪問一個聚合對象(如列表、樹、圖等)中的元素,而無需暴露集合的內(nèi)部結(jié)構(gòu)。
1.1、結(jié)構(gòu)
關(guān)于Collection接口,繼承于Iterable接口。
Java 的集合框架(如List、Set)均實現(xiàn)了Iterator接口,通過iterator()方法返回迭代器:
代碼示例如下:
public interface Collection<E> extends Iterable<E> {}
public interface Iterable<T> {
Iterator<T> iterator();
}通過迭代器模式,可以將集合的遍歷邏輯與集合本身的實現(xiàn)解耦,從而提高代碼的靈活性和可維護性。
1.2、常用方法
它通常包含以下核心方法:
- hasNext():判斷是否還有下一個元素。
- next():獲取下一個元素。
- remove()(可選):刪除當前元素。
代碼示例:
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
1.3、本質(zhì)
迭代器被歸類java設(shè)計模式里面的行為型設(shè)計模式(Behavioral Design Pattern),定義了對象之間的交互方式。
它的核心思想是:
解耦遍歷邏輯與數(shù)據(jù)結(jié)構(gòu),使客戶端無需關(guān)心數(shù)據(jù)的存儲方式即可統(tǒng)一訪問元素。
1、解耦集合與遍歷邏輯
- 傳統(tǒng)方式:直接通過索引遍歷集合(如數(shù)組),客戶端需要知道集合的內(nèi)部結(jié)構(gòu)(如數(shù)組長度)。
- 迭代器方式:客戶端只需調(diào)用hasNext()和next(),無需關(guān)心集合是數(shù)組、鏈表還是樹。
2、統(tǒng)一訪問接口
- 不同類型的集合(如List、Set、Map)可以提供自己的迭代器實現(xiàn),客戶端通過統(tǒng)一的Iterator接口操作。
3、支持多種遍歷方式
- 迭代器可以定義不同的遍歷策略(如正向、逆向、深度優(yōu)先搜索等),而集合本身不需要修改。
4、提高代碼復用性
- 迭代器模式將遍歷邏輯抽象為獨立的對象,可以被多個集合復用。
1.4、自定義迭代器
// 自定義集合
class MyCollection implements Iterable<Integer> {
private List<Integer> data = new ArrayList<>();
public void add(int value) {
data.add(value);
}
@Override
public Iterator<Integer> iterator() {
return new MyIterator();
}
// 自定義迭代器
private class MyIterator implements Iterator<Integer> {
private int index = 0;
@Override
public boolean hasNext() {
return index < data.size();
}
@Override
public Integer next() {
return data.get(index++);
}
}
}
總結(jié)

2、迭代器模式的組成
2.1、迭代器模式角色
1、抽象迭代器(Iterator):
定義了遍歷聚合對象所需的方法,包括hashNext()和next()方法等,用于遍歷聚合對象中的元素。
2、具體迭代器(Concrete Iterator):
它是實現(xiàn)迭代器接口的具體實現(xiàn)類,負責具體的遍歷邏輯。它保存了當前遍歷的位置信息,并可以根據(jù)需要向前或向后遍歷集合元素。
3、抽象聚合器(Aggregate):
一般是一個接口,提供一個iterator()方法,例如java中的Collection接口,List接口,Set接口等。
4、具體聚合器(ConcreteAggregate):
就是抽象容器的具體實現(xiàn)類,比如List接口的有序列表實現(xiàn)ArrayList,List接口的鏈表實現(xiàn)LinkList,Set接口的哈希列表的實現(xiàn)HashSet等。
2.2、UML 類圖
如下所示:

2.3、舉例
下面以班級名單為例,解釋一下迭代器模式。
- 抽象迭代器:StudentIterator
- 具體迭代器:StudentListIterator
- 抽象聚合器:StudentAggregate
- 具體聚合器:ClassList

1、Student——學生實體類
首先定義一個學生類,用來表示學生信息。
如下圖所示:
/**
* @author Created by njy on 2023/6/25
* 學生實體類
*/
@Data
public class Student {
private String name;
private Integer age;
public Student(String name,Integer age){
this.age=age;
this.name=name;
}
}2、StudentIterator——抽象迭代器(Iterator)
創(chuàng)建一個抽象迭代器(學生迭代器)并繼承Iterator接口(java.util包下的Iterator)。
如下所示:
import java.util.Iterator;
/**
* @author Created by njy on 2023/6/25
* 抽象迭代器(Iterator):學生迭代器
* 實現(xiàn)Iterator接口
* 負責定義訪問和遍歷元素的接口,例如提供hasNext()和next()方法。
*/
public interface StudentIterator extends Iterator<Student> {
}3、StudentListIterator——具體迭代器(Concrete iterator)
在這個具體迭代器中,實現(xiàn)抽象迭代器,重寫hashNext()和next()方法。
如下所示:
/**
* @author Created by njy on 2023/6/25
* 具體迭代器(Concrete iterator):
* 實現(xiàn)抽象迭代器定義的接口,負責實現(xiàn)對元素的訪問和遍歷。
*/
public class StudentListIterator implements StudentIterator{
private List<Student> students;
private int index;
public StudentListIterator(List<Student> students) {
this.students = students;
this.index = 0;
}
//檢查是否還有下一個元素
@Override
public boolean hasNext() {
return (index < students.size());
}
//返回下一個元素
@Override
public Student next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Student student = students.get(index);
index++;
return student;
}
}4、StudentAggregate——抽象聚合器(Aggregate)
定義一個抽象聚合器,并定義一個iterator()方法,用于創(chuàng)建具體的迭代器對象。
如下所示:
/**
* @author Created by njy on 2023/6/25
* 抽象聚合器(Aggregate):學生聚合器
* 提供創(chuàng)建迭代器的接口,例如可以定義一個iterator()方法。
*/
public interface StudentAggregate {
//用于創(chuàng)建具體的迭代器對象
StudentIterator iterator();
void add(Student student);
}5、ClassList——具體聚合器(Concrete Aggregate)
實現(xiàn)抽象聚合器定義的接口,負責創(chuàng)建具體的迭代器對象。
如下所示:
/**
* @author Created by njy on 2023/6/25
* 具體聚合器(ConcreteAggregate):班級列表
* 實現(xiàn)抽象聚合器定義的接口,負責創(chuàng)建具體的迭代器對象,并返回該對象。
*/
public class ClassList implements StudentAggregate{
private List<Student> students = new ArrayList<>();
//創(chuàng)建迭代器對象
@Override
public StudentIterator iterator() {
return new StudentListIterator(students);
}
//向班級名單中添加學生信息
@Override
public void add(Student student) {
students.add(student);
}
}6、testIterator
/**
* @author Created by njy on 2023/6/25
* 迭代器模式測試類
*/
@SpringBootTest
public class TestIterator {
@Test
void testIterator(){
ClassList classList = new ClassList();
// 添加學生信息
classList.add(new Student("張三", 18));
classList.add(new Student("李四", 19));
classList.add(new Student("王五", 20));
// 獲取迭代器,遍歷學生信息
StudentIterator iterator = classList.iterator();
while(iterator.hasNext()) {
Student student = iterator.next();
System.out.println("學生姓名:" + student.getName() + ",學生年齡:" + student.getAge());
}
}
}
輸出:
學生姓名:張三,學生年齡:18
學生姓名:李四,學生年齡:19
學生姓名:王五,學生年齡:203、實際應用
1、集合框架中的迭代器:
在Java中,集合包括List、Set、Map等等,每個集合類中都提供了一個獲取迭代器的方法,例如List提供的iterator()方法、Set提供的iterator()方法等等。
通過獲取對應的迭代器對象,可以對集合中的元素進行遍歷和訪問。
代碼示例:
import java.util.*;
public class CollectionIteratorExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
2、JDBC中的ResultSet對象:
在Java中,如果需要對數(shù)據(jù)庫中的數(shù)據(jù)進行遍歷和訪問,可以使用JDBC操作數(shù)據(jù)庫。
JDBC中,查詢結(jié)果集使用ResultSet對象來表示,通過使用ResultSet的next()方法,就可以像使用迭代器一樣遍歷和訪問查詢結(jié)果中的數(shù)據(jù)。
代碼示例:
import java.sql.*;
import java.util.Iterator;
public class JdbcIteratorExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name FROM users")) {
// 使用自定義迭代器遍歷 ResultSet
Iterator<User> userIterator = new ResultSetIterator<>(rs);
while (userIterator.hasNext()) {
User user = userIterator.next();
System.out.println(user);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// 自定義迭代器
static class ResultSetIterator<T> implements Iterator<T> {
private final ResultSet rs;
private final RowMapper<T> rowMapper;
public ResultSetIterator(ResultSet rs) throws SQLException {
this.rs = rs;
this.rowMapper = (rs1) -> {
User user = new User();
user.setId(rs1.getInt("id"));
user.setName(rs1.getString("name"));
return user;
};
}
@Override
public boolean hasNext() throws SQLException {
return rs.next();
}
@Override
public T next() throws SQLException {
return rowMapper.mapRow(rs);
}
}
// 輔助類
static class User {
private int id;
private String name;
// Getters and setters
@Override
public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + '}';
}
}
interface RowMapper<T> {
T mapRow(ResultSet rs) throws SQLException;
}
}
3、文件讀?。?/strong>
在Java中,我們可以使用BufferedReader類來讀取文本文件。BufferedReader類提供了一個方法readLine()來逐行讀取文件內(nèi)容。
BufferedReader在內(nèi)部使用了迭代器模式來逐行讀取文本文件的內(nèi)容。
代碼示例:
import java.io.*;
import java.util.Iterator;
public class FileIteratorExample {
public static void main(String[] args) {
String filePath = "example.txt";
try (FileReader reader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(reader)) {
// 使用自定義迭代器遍歷文件
Iterator<String> lineIterator = new LineIterator(bufferedReader);
while (lineIterator.hasNext()) {
System.out.println(lineIterator.next());
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 自定義迭代器
static class LineIterator implements Iterator<String> {
private final BufferedReader reader;
private String nextLine;
public LineIterator(BufferedReader reader) throws IOException {
this.reader = reader;
this.nextLine = reader.readLine();
}
@Override
public boolean hasNext() {
try {
return nextLine != null || (nextLine = reader.readLine()) != null;
} catch (IOException e) {
throw new RuntimeException("讀取文件時出錯", e);
}
}
@Override
public String next() {
if (!hasNext()) {
throw new IllegalStateException("沒有更多行");
}
String currentLine = nextLine;
try {
nextLine = reader.readLine();
} catch (IOException e) {
throw new RuntimeException("讀取文件時出錯", e);
}
return currentLine;
}
}
}
4、優(yōu)缺點
4.1、優(yōu)點
1、隱藏集合實現(xiàn)細節(jié)
- 客戶端無需知道集合是鏈表、數(shù)組還是其他結(jié)構(gòu),只需通過迭代器操作。
2、支持并發(fā)修改
- 某些迭代器(如 Java 的ConcurrentHashMap的弱一致性迭代器)可以處理并發(fā)修改,避免ConcurrentModificationException??蓞⒖迹?a href="/program/3445174sd.htm" rel="external nofollow" target="_blank">集合中的并發(fā)修改異常及處理方式
3、靈活的遍歷方式
- 例如,可以為樹結(jié)構(gòu)定義深度優(yōu)先或廣度優(yōu)先的迭代器。
4、代碼簡潔性
- 使用迭代器可以避免重復編寫遍歷邏輯(如手動管理索引)。
4.2、缺點
- 增加了代碼復雜度:需要額外定義迭代器類。
- 性能開銷:對于簡單集合(如數(shù)組),直接遍歷可能更高效。
總結(jié)
迭代器模式是 Java 集合框架的核心設(shè)計之一,也是許多高級數(shù)據(jù)結(jié)構(gòu)(如樹、圖)遍歷的基礎(chǔ)。通過理解其原理,可以更高效地設(shè)計和實現(xiàn)符合要求的集合類。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實現(xiàn)從數(shù)據(jù)庫導出大量數(shù)據(jù)記錄并保存到文件的方法
這篇文章主要介紹了Java實現(xiàn)從數(shù)據(jù)庫導出大量數(shù)據(jù)記錄并保存到文件的方法,涉及Java針對數(shù)據(jù)庫的讀取及文件寫入等操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11
java如何將Object數(shù)組轉(zhuǎn)換為指定類型數(shù)組
這篇文章主要介紹了java如何將Object數(shù)組轉(zhuǎn)換為指定類型數(shù)組,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
詳解基于java的Socket聊天程序——服務端(附demo)
這篇文章主要介紹了詳解基于java的Socket聊天程序——服務端(附demo),具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-12-12

