Java設(shè)計模式中的迭代器模式詳解
一 定義
提供一個對象來順序訪問聚合對象中的一系列數(shù)據(jù),而不暴露聚合對象的內(nèi)部表示。
二 UML類圖
- 抽象聚合(Aggregate)角色:定義存儲、添加、刪除聚合元素以及創(chuàng)建迭代器對象的接口。
- 具體聚合(ConcreteAggregate)角色:實(shí)現(xiàn)抽象聚合類,返回一個具體迭代器的實(shí)例。
- 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的接口,通常包含 hasNext()、next() 等方法。
- 具體迭代器(Concretelterator)角色:實(shí)現(xiàn)抽象迭代器接口中所定義的方法,完成對聚合對象的遍歷,記錄遍歷的當(dāng)前位置。
三 代碼實(shí)例
【例】定義一個可以存儲學(xué)生對象的容器對象,將遍歷該容器的功能交由迭代器實(shí)現(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>(); // 學(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)
- 它支持以不同的方式遍歷一個聚合對象,在同一個聚合對象上可以定義多種遍歷方式。在迭代器模式中只需要用一個不同的迭代器來替換原有迭代器即可改變遍歷算法,我們也可以自己定義迭代器的子類以支持新的遍歷方式。
- 迭代器簡化了聚合類。由于引入了迭代器,在原有的聚合對象中不需要再自行提供數(shù)據(jù)遍歷等方法,這樣可以簡化聚合類的設(shè)計。
- 在迭代器模式中,由于引入了抽象層,增加新的聚合類和迭代器類都很方便,無須修改原有代碼,滿足 “開閉原則” 的要求。
4.2 缺點(diǎn)
增加了類的個數(shù),這在一定程度上增加了系統(tǒng)的復(fù)雜性。
五 使用場景
- 當(dāng)需要為聚合對象提供多種遍歷方式時。
- 當(dāng)需要為遍歷不同的聚合結(jié)構(gòu)提供一個統(tǒng)一的接口時。
- 當(dāng)訪問一個聚合對象的內(nèi)容而無須暴露其內(nèi)部細(xì)節(jié)的表示時。
六 JDK迭代器的運(yùn)用
迭代器模式在JAVA的很多集合類中被廣泛應(yīng)用,接下來看看JAVA源碼中是如何使用迭代器模式的。
List<String> list = new ArrayList<>(); Iterator<String> iterator = list.iterator(); //list.iterator()方法返回的肯定是Iterator接口的子實(shí)現(xiàn)類對象 while (iterator.hasNext()) { System.out.println(iterator.next()); }
看完這段代碼是不是很熟悉,與我們上面代碼基本類似。單列集合都使用到了迭代器,我們以ArrayList舉例來說明
- List:抽象聚合類
- ArrayList:具體的聚合類
- Iterator:抽象迭代器
- list.iterator():返回的是實(shí)現(xiàn)了 Iterator 接口的具體迭代器對象
具體的來看看 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; // 下一個要返回元素的索引 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 方法中返回了一個實(shí)例化的 Iterator 對象。Itr是一個內(nèi)部類,它實(shí)現(xiàn)了 Iterator 接口并重寫了其中的抽象方法。
注意:
當(dāng)我們在使用JAVA開發(fā)的時候,想使用迭代器模式的話,只要讓我們自己定義的容器類實(shí)現(xiàn)java.util.Iterable并實(shí)現(xiàn)其中的iterator()方法使其返回一個 java.util.Iterator 的實(shí)現(xiàn)類就可以了
到此這篇關(guān)于Java設(shè)計模式中的迭代器模式詳解的文章就介紹到這了,更多相關(guān)Java迭代器模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java用POI解析excel并獲取所有單元格數(shù)據(jù)的實(shí)例
下面小編就為大家?guī)硪黄狫ava用POI解析excel并獲取所有單元格數(shù)據(jù)的實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10SpringBoot設(shè)置Json返回字段為非空問題
這篇文章主要介紹了SpringBoot設(shè)置Json返回字段為非空問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08Java使用動態(tài)規(guī)劃算法思想解決背包問題
背包問題(Knapsack problem)是一種組合優(yōu)化的NP完全問題。問題可以描述為:給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內(nèi),我們?nèi)绾芜x擇,才能使得物品的總價格最高2022-04-04java實(shí)戰(zhàn)CPU占用過高問題的排查及解決
這篇文章給大家分享了java實(shí)戰(zhàn)CPU占用過高問題的排查及解決方法,有需要的朋友們可以學(xué)習(xí)下。2018-08-08Spring中@Value讀取properties作為map或list的操作
這篇文章主要介紹了Spring中@Value讀取properties作為map或list的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07