Java設(shè)計(jì)模式中的迭代器模式詳解
一 定義
提供一個(gè)對(duì)象來(lái)順序訪(fǎng)問(wèn)聚合對(duì)象中的一系列數(shù)據(jù),而不暴露聚合對(duì)象的內(nèi)部表示。
二 UML類(lèi)圖

- 抽象聚合(Aggregate)角色:定義存儲(chǔ)、添加、刪除聚合元素以及創(chuàng)建迭代器對(duì)象的接口。
- 具體聚合(ConcreteAggregate)角色:實(shí)現(xiàn)抽象聚合類(lèi),返回一個(gè)具體迭代器的實(shí)例。
- 抽象迭代器(Iterator)角色:定義訪(fǎng)問(wèn)和遍歷聚合元素的接口,通常包含 hasNext()、next() 等方法。
- 具體迭代器(Concretelterator)角色:實(shí)現(xiàn)抽象迭代器接口中所定義的方法,完成對(duì)聚合對(duì)象的遍歷,記錄遍歷的當(dāng)前位置。
三 代碼實(shí)例
【例】定義一個(gè)可以存儲(chǔ)學(xué)生對(duì)象的容器對(duì)象,將遍歷該容器的功能交由迭代器實(shí)現(xiàn),涉及到的類(lèi)如下:

定義迭代器接口,聲明hasNext、next方法:
public interface StudentIterator {
boolean hasNext();
Student next();
}
定義具體的迭代器類(lèi),重寫(xiě)所有的抽象方法”
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;
}
}
定義抽象容器類(lèi),包含添加元素,刪除元素,獲取迭代器對(duì)象的方法:
public interface StudentAggregate {
void addStudent(Student student);
void removeStudent(Student student);
StudentIterator getStudentIterator();
}
定義具體的容器類(lèi),重寫(xiě)所有的方法:
public class StudentAggregateImpl implements StudentAggregate {
private List<Student> list = new ArrayList<Student>(); // 學(xué)生列表
@Override
public void addStudent(Student student) {
this.list.add(student);
}
@Override
public void removeStudent(Student student) {
this.list.remove(student);
}
@Override
public StudentIterator getStudentIterator() {
return new StudentIteratorImpl(list);
}
}
四 迭代器模式的優(yōu)缺點(diǎn)
4.1 優(yōu)點(diǎn)
- 它支持以不同的方式遍歷一個(gè)聚合對(duì)象,在同一個(gè)聚合對(duì)象上可以定義多種遍歷方式。在迭代器模式中只需要用一個(gè)不同的迭代器來(lái)替換原有迭代器即可改變遍歷算法,我們也可以自己定義迭代器的子類(lèi)以支持新的遍歷方式。
- 迭代器簡(jiǎn)化了聚合類(lèi)。由于引入了迭代器,在原有的聚合對(duì)象中不需要再自行提供數(shù)據(jù)遍歷等方法,這樣可以簡(jiǎn)化聚合類(lèi)的設(shè)計(jì)。
- 在迭代器模式中,由于引入了抽象層,增加新的聚合類(lèi)和迭代器類(lèi)都很方便,無(wú)須修改原有代碼,滿(mǎn)足 “開(kāi)閉原則” 的要求。
4.2 缺點(diǎn)
增加了類(lèi)的個(gè)數(shù),這在一定程度上增加了系統(tǒng)的復(fù)雜性。
五 使用場(chǎng)景
- 當(dāng)需要為聚合對(duì)象提供多種遍歷方式時(shí)。
- 當(dāng)需要為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口時(shí)。
- 當(dāng)訪(fǎng)問(wèn)一個(gè)聚合對(duì)象的內(nèi)容而無(wú)須暴露其內(nèi)部細(xì)節(jié)的表示時(shí)。
六 JDK迭代器的運(yùn)用
迭代器模式在JAVA的很多集合類(lèi)中被廣泛應(yīng)用,接下來(lái)看看JAVA源碼中是如何使用迭代器模式的。
List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator(); //list.iterator()方法返回的肯定是Iterator接口的子實(shí)現(xiàn)類(lèi)對(duì)象
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
看完這段代碼是不是很熟悉,與我們上面代碼基本類(lèi)似。單列集合都使用到了迭代器,我們以ArrayList舉例來(lái)說(shuō)明
- List:抽象聚合類(lèi)
- ArrayList:具體的聚合類(lèi)
- Iterator:抽象迭代器
- list.iterator():返回的是實(shí)現(xiàn)了 Iterator 接口的具體迭代器對(duì)象
具體的來(lái)看看 ArrayList的代碼實(shí)現(xiàn)
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
public Iterator<E> iterator() {
return new ArrayList.Itr();
}
private class Itr implements Iterator<E> {
int cursor; // 下一個(gè)要返回元素的索引
int lastRet = -1; // 上一個(gè)返回元素的索引
int expectedModCount = modCount;
Itr() {}
//判斷是否還有元素
public boolean hasNext() {
return cursor != size;
}
//獲取下一個(gè)元素
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];
}
...
}
}
這部分代碼還是比較簡(jiǎn)單,大致就是在 iterator 方法中返回了一個(gè)實(shí)例化的 Iterator 對(duì)象。Itr是一個(gè)內(nèi)部類(lèi),它實(shí)現(xiàn)了 Iterator 接口并重寫(xiě)了其中的抽象方法。
注意:
當(dāng)我們?cè)谑褂肑AVA開(kāi)發(fā)的時(shí)候,想使用迭代器模式的話(huà),只要讓我們自己定義的容器類(lèi)實(shí)現(xiàn)java.util.Iterable并實(shí)現(xiàn)其中的iterator()方法使其返回一個(gè) java.util.Iterator 的實(shí)現(xiàn)類(lèi)就可以了
到此這篇關(guān)于Java設(shè)計(jì)模式中的迭代器模式詳解的文章就介紹到這了,更多相關(guān)Java迭代器模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
AsyncConfigurerSupport自定義異步線(xiàn)程池處理異常
這篇文章主要為大家介紹了AsyncConfigurerSupport自定義異步線(xiàn)程池處理異常詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
java實(shí)現(xiàn)從網(wǎng)絡(luò)下載多個(gè)文件
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)從網(wǎng)絡(luò)下載多個(gè)文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
SpringMVC實(shí)現(xiàn)Controller的三種方式總結(jié)
這篇文章主要介紹了SpringMVC實(shí)現(xiàn)Controller的三種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java service層獲取HttpServletRequest工具類(lèi)的方法
今天小編就為大家分享一篇關(guān)于Java service層獲取HttpServletRequest工具類(lèi)的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12
Maven的生命周期與自定義插件實(shí)現(xiàn)方法
Maven的生命周期就是對(duì)所有的構(gòu)建過(guò)程進(jìn)行抽象和統(tǒng)一。包含了項(xiàng)目的清理、初始化、編譯、測(cè)試、打包、集成測(cè)試、驗(yàn)證、部署和站點(diǎn)生成等幾乎所有的構(gòu)建步驟2022-12-12

