Java設計模式之迭代器模式解析
概述
定義
提供一個對象來順序訪問聚合對象中的一系列數(shù)據(jù),而不暴露聚合對象的內(nèi)部表示。
結(jié)構(gòu)
迭代器模式 (Iterator Pattern) 主要包含以下角色:
- 抽象聚合(Aggregate)角色:定義存儲、添加、刪除聚合元素以及創(chuàng)建迭代器對象的接口。
- 具體聚合(Concrete Aggregate)角色:實現(xiàn)抽象聚合類,返回一個具體迭代器的實例。
- 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的接口,通常包含 hasNext()、next() 等方法。
- 具體迭代器(Concrete lterator)角色:實現(xiàn)抽象迭代器接口中所定義的方法,完成對聚合對象的遍歷,記錄遍歷的當前位置。
案例實現(xiàn)
【例】定義一個可以存儲學生對象的容器對象,將遍歷該容器的功能交由迭代器實現(xiàn),涉及到的類如下:

代碼如下:
- 抽象迭代器角色-迭代器接口,聲明 hasNext()、next() 方法
public interface StudentIterator {
// 判斷是否還有元素
boolean hasNext();
// 獲取下一個元素
Student next();
}- 具體迭代器角色類,重寫所有的抽象方法
public class StudentIteratorImpl implements StudentIterator {
private List<Student> list;
private int position = 0; // 記錄遍歷時的位置
public StudentIteratorImpl(List<Student> list) {
this.list = list;
}
// 判斷是否還有元素
@Override
public boolean hasNext() {
return position < list.size();
}
// 獲取下一個元素
@Override
public Student next() {
// 從集合中獲取指定位置的元素
Student currentStudent = list.get(position);
position++;
return currentStudent;
}
}- 抽象容器類(抽象聚合角色),包含添加元素,刪除元素,獲取迭代器對象的方法
public interface StudentAggregate {
// 添加學生功能
void addStudent(Student student);
// 刪除學生功能
void removeStudent(Student student);
// 獲取迭代器對象功能
StudentIterator getStudentIterator();
}- 具體的容器類(具體聚合角色),重寫所有的方法
public class StudentAggregateImpl implements StudentAggregate {
private List<Student> list = new ArrayList<Student>(); // 學生列表
// 添加學生功能
@Override
public void addStudent(Student student) {
this.list.add(student);
}
// 刪除學生功能
@Override
public void removeStudent(Student student) {
this.list.remove(student);
}
// 獲取迭代器對象功能
@Override
public StudentIterator getStudentIterator() {
// 創(chuàng)建迭代器對象
return new StudentIteratorImpl(list);
}
}- 學生類
public class Student {
private String name;
private String number;
// getter/setter...
public Student(String name, String number) {
this.name = name;
this.number = number;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", number='" + number + '\'' +
'}';
}
}- 測試類
public class Client {
public static void main(String[] args) {
// 創(chuàng)建聚合對象
StudentAggregateImpl aggregate = new StudentAggregateImpl();
// 添加元素
aggregate.addStudent(new Student("張三", "001"));
aggregate.addStudent(new Student("李四", "002"));
aggregate.addStudent(new Student("王五", "003"));
aggregate.addStudent(new Student("趙六", "004"));
/*
* 遍歷聚合對象
*/
// 1.獲取迭代器對象
StudentIterator iterator = aggregate.getStudentIterator();
// 2.遍歷
while (iterator.hasNext()) {
// 3.獲取元素
Student student = iterator.next();
System.out.println(student.toString());
}
}
}輸出
Student{name='張三', number='001'}
Student{name='李四', number='002'}
Student{name='王五', number='003'}
Student{name='趙六', number='004'}
優(yōu)缺點
優(yōu)點
- 它支持以不同的方式遍歷一個聚合對象,在同一個聚合對象上可以定義多種遍歷方式。在迭代器模式中只需要用一個不同的迭代器來替換原有迭代器即可改變遍歷算法,我們也可以自己定義迭代器的子類以支持新的遍歷方式。
- 迭代器簡化了聚合類。由于引入了迭代器,在原有的聚合對象中不需要再自行提供數(shù)據(jù)遍歷等方法,這樣可以簡化聚合類的設計。
- 在迭代器模式中,由于引入了抽象層,增加新的聚合類和迭代器類都很方便,無須修改原有代碼,滿足“開閉原則”的要求。
缺點
- 增加了類的個數(shù),這在一定程度上增加了系統(tǒng)的復雜性。
使用場景
- 當需要為聚合對象提供多種遍歷方式時。
- 當需要為遍歷不同的聚合結(jié)構(gòu)提供一個統(tǒng)一的接口時。
- 當訪問一個聚合對象的內(nèi)容而無須暴露其內(nèi)部細節(jié)的表示時。
JDK源碼解析-集合類
迭代器模式在 java 的很多集合類中被廣泛應用,接下來看看 java 源碼中是如何使用迭代器模式的。
List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator(); // list.iterator()方法返回的肯定是Iterator接口的子實現(xiàn)類對象
while (iterator.hasNext()) {
System.out.println(iterator.next());
}看完這段代碼是不是很熟悉,與我們上面代碼基本類似。單列集合都使用到了迭代器,我們以 ArrayList 舉例來說明:
- List:抽象聚合類
- ArrayList:具體的聚合類
- Iterator:抽象迭代器
- list.iterator():返回的是實現(xiàn)了 Iterator 接口的具體迭代器對象(在 ArrayList 中就是內(nèi)部類 Itr)
具體的來看看 ArrayList 的代碼實現(xiàn):
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
public Iterator<E> iterator() {
// 返回的肯定是Iterator的子實現(xiàn)類對象
return new Itr();
}
||
\/
// 內(nèi)部類Itr 實現(xiàn)了Iterator接口 并且重寫了 hasNext() 和 next() 方法。
private class Itr implements Iterator<E> {
int cursor; // 下一個要返回元素的索引
int lastRet = -1; // 上一個返回元素的索引
int expectedModCount = modCount;
Itr() {}
// 判斷是否還有元素
public boolean hasNext() {
return cursor != size;
}
// 獲取下一個元素
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
...
}這部分代碼還是比較簡單,大致就是在 iterator 方法中返回了一個實例化的 Iterator 對象,Itr 是一個內(nèi)部類,它實現(xiàn)了 Iterator 接口并重寫了其中的抽象方法。
注意:
當我們在使用 java 開發(fā)的時候,想使用迭代器模式的話,只要讓我們自己定義的容器類實現(xiàn) java.util.Iterable 并實現(xiàn)其中的 iterator() 方法使其返回一個 java.util.Iterator 的實現(xiàn)類就可以了。
到此這篇關(guān)于Java設計模式之迭代器模式解析的文章就介紹到這了,更多相關(guān)Java的迭代器模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 數(shù)據(jù)庫時間返回前端顯示錯誤(差8個小時)的解決方法
本文主要介紹了Java 數(shù)據(jù)庫時間返回前端顯示錯誤(差8個小時)的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-08-08
Java Web項目創(chuàng)建并實現(xiàn)前后端交互
本文主要介紹了Java Web項目創(chuàng)建并實現(xiàn)前后端交互,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07
Postman form-data、x-www-form-urlencoded的區(qū)別及說明
這篇文章主要介紹了Postman form-data、x-www-form-urlencoded的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
詳解MyBatisPlus如何實現(xiàn)分頁和查詢操作
這篇文章主要為大家詳細介紹了MyBatisPlus是如何實現(xiàn)分頁和查詢操作的,文中的示例代碼講解詳細,對我們學習有一定的幫助,需要的可以參考一下2022-05-05

