被用到爐火純清的迭代器模式

點擊上方「藍字」關注我們

0x01:迭代器模式簡介
Java中可以說已經(jīng)把迭代器模式用到了極致,每一個集合類都關聯(lián)了一個迭代器類Iterator。
迭代器模式(Iterator),提供一種方法順序訪問一個聚合對象中的各種元素,而又不暴露該對象的內(nèi)部表示。UML類圖如下:

其中,Aggregate是聚集抽象類,負責提供創(chuàng)建具體迭代器角色的接口;Iterator是迭代抽象類,用于定義得到開始對象、得到下一個對象、判斷是否到結尾、當前對象等抽象方法,統(tǒng)一接口;ConcreteAggregate是具體聚集類,繼承Aggregate;ConcreteIterator是具體迭代器類,繼承Iterator,實現(xiàn)開始、下一個、是否結尾、當前對象等方法。具體角色說明:
Iterator(迭代器):迭代器定義訪問和遍歷元素的接口;
ConcreteIterator (具體迭代器):具體迭代器實現(xiàn)迭代器接口,對該聚合遍歷時跟蹤當前位置;
Aggregate (聚合):聚合定義創(chuàng)建相應迭代器對象的接口;
ConcreteAggregate (具體聚合):具體聚合實現(xiàn)創(chuàng)建相應迭代器的接口,該操作返回ConcreteIterator的一個適當?shù)膶嵗?/span>
0x02:迭代器模式實現(xiàn)
抽象聚合:負責提供接口,比如定義一個類似createIterator()這樣的方法,在Java集合類里一般是iterator()方法。
public?interface?Aggregate?{
????public?void?add(Object?object);
????public?void?remove(Object?object);
????public?Iterator?iterator();
}
抽象迭代器:負責定義訪問和遍歷元素的接口,基本上有固定的三個方法,即first()獲取第一個元素、next()訪問下一個元素、hasNext()判斷已經(jīng)遍歷到最后。
public?interface?Iterator?{
????public?Object?next();????//遍歷到下一個元素
????public?boolean?hasNext();????//是否已經(jīng)遍歷到尾部
????public?boolean?remove();????//刪除當前指向的元素
}
具體聚合
public?class?ConcreteAggregate?implements?Aggregate?{
????private?List?list =?new?ArrayList();
????@Override
????public?void?add(Object?object)?{
????????this.list.add(object);
????}
????public?void?remove(Object?object)?{
????????this.list.remove(object);
????}
????@Override
????public?Iterator?iterator()?{
????????return?new?ConcreteIterator(this.list);
????}
}
具體迭代器:簡單的實現(xiàn)就是通過一個游標,在一個容器中前后移動,遍歷所有它需要查看的元素
public?class?ConcreteIterator?implements?Iterator?{
????private?List?list=?new?ArrayList();
????public?int?cursor?=?0;????//定義當前游標
????public?ConcreteIterator(List?list)?{
????????this.list=?list;
????}
????@Override
????public?Object?next()?{
????????Object?result?=?null;
????????if?(this.hasNext())?{
????????????result?=?this.list.get(this.cursor);
????????????this.cursor?=?this.cursor?+?1;
????????}?else?{
????????????result?=?null;
????????}
????????return?result;
????}
????@Override
????public?boolean?hasNext()?{
????????if?(this.cursor?==?this.list.size())?{
????????????return?false;
????????}
????????return?true;
????}
????@Override
????public?boolean?remove()?{
????????this.list.remove(this.cursor);
????????return?true;
????}
}
迭代器模式測試代碼
注意引入自己定義的Iterator類,而不是Java內(nèi)部封裝好的java.util.Iterator類。
public?class?Client?{
????public?static?void?main(String[]?args)?{
????????Aggregate?aggregate?=?new?ConcreteAggregate();
????????aggregate.add("java樂園");
????????aggregate.add("架構師知音");
????????aggregate.add("非常架構");
????????//遍歷
????????Iterator?iterator?=?aggregate.iterator();
????????while?(iterator.hasNext())?{
????????????System.out.println(iterator.next());
????????}
????}
}
0x03:JDK中的迭代器源碼分析
在JDK涉及到的迭代器Iterator都與集合有關,主要相關實現(xiàn)在java.util包下。下面以 ArrayList 為例進行分析:
java.lang.Iterable類:表示一個可以被迭代的對象
public?interface?Iterable<T>?{
????Iterator?iterator() ;
????default?void?forEach(Consumer?super?T>?action)?{
????????Objects.requireNonNull(action);
????????for?(T?t?:?this)?{
????????????action.accept(t);
????????}
????}
????default?Spliterator?spliterator()? {
????????return?Spliterators.spliteratorUnknownSize(iterator(),?0);
????}
}
java.util.Iterator:表示抽象迭代器
public?interface?Iterator<E>?{boolean?hasNext();????E?next();
????default?void?remove()?{
????????throw?new?UnsupportedOperationException("remove");
????}
????default?void?forEachRemaining(Consumer?super?E>?action)?{
????????Objects.requireNonNull(action);
????????while?(hasNext())
????????????action.accept(next());
????}
}
java.util.Collection:表示抽象聚合對象
public?interface?Collection<E>?extends?Iterable<E>?{
????Iterator?iterator() ;
????boolean?add(E?e);
????boolean?remove(Object?o);
????boolean?addAll(Collection?extends?E>?c);
????boolean?removeAll(Collection>?c);
????//其他省略
?????.......
}
java.util.AbstractList.Itr:具體迭代器實現(xiàn)類,該類是 java.util.AbstractList 類的一個內(nèi)部類
private?class?ListItr?extends?Itr?implements?ListIterator<E>?{
????????//具體代碼省略.......}
java.util.ArrayList:具體聚合對象
public?class?ArrayList<E>?extends?AbstractList<E>
????????implements?List<E>,?RandomAccess,?Cloneable,?java.io.Serializable
{
?????//具體代碼省略
?????.......
}
java.util.ArrayList整體實現(xiàn)UML類圖

[來源:https://www.alicharles.com/article/design-pattern/jdk-iterator-pattern/]
研讀JDK源碼的迭代器模式,可以非常有效的學習和理解迭代器模式。從代碼上看JDK的迭代器源碼比小編實現(xiàn)的復雜很多,但是基本原理無兩。常常研讀大神的源碼有利于提升技術能力。

掃碼二維碼
獲取更多精彩
Java樂園

