迭代器模式(Iterator Pattern)
屬於行爲型模式
的一種,提供一種方法訪問一個容器中各個元素,而又不須要暴露該對象的內部細節。java
<!-- more -->git
迭代器模式
聽起來可能感受很陌生,可是實際上,迭代器模式
是全部設計模式中最簡單也是最經常使用的設計模式,正是由於太經常使用了,因此致使不少人忽略了它的存在。spring
在實際的開發過程當中,咱們可能須要針對不一樣的需求,可能須要以不一樣的方式來遍歷整個整合對象,但又不但願在聚合對象的抽象接口層中充斥着各類不一樣的便利操做。這個時候咱們就須要這樣一種東西,它應該具有以下三個功能:設計模式
迭代器模式: 把在元素之間遊走的責任交給迭代器,而不是聚合對象。簡化了聚合的接口和實現,讓聚合更專一在它所應該專一的事情上,這樣作更加符合單一責任原則。springboot
UML結構圖微信
模式結構微信公衆平臺
具體迭代器
須要實現的接口,提供了遊走聚合對象元素之間的方法createIterator()
用於建立一個迭代器對象,充當抽象迭代器工廠角色createIterator()
,該方法返回一個與該具體聚合類對應的具體迭代器ConcreteIterator
實例。UML圖以下:ide
1.先定義抽象迭代器``測試
interface Iterator<E> { //判斷是否有還有下一個元素 boolean hasNext(); //取出下一個對象 E next(); }
2.在定義一個具體迭代器對象,實現了Iterator
中的方法ui
class MusicIterator<E> implements Iterator<E> { private E[] es; private int position = 0; public MusicIterator(E[] es) { this.es = es; } @Override public boolean hasNext() { return position != es.length; } @Override public E next() { E e = es[position]; position += 1; return e; } }
3.接下來定義抽象聚合類(常爲 Collection , List , Set 等)
interface AbstractList<E> { void add(E e); Iterator<E> createIterator(); }
4.最後建立具體聚合類 (常爲 ArrayList , HashSet 等,是抽象聚合類的實現類)
class MusicList implements AbstractList<String> { private String[] books = new String[5]; private int position = 0; @Override public void add(String name) { books[position] = name; position += 1; } @Override public Iterator<String> createIterator() { return new MusicIterator<>(books); } }
5.建立測試工程
public class Client { public static void main(String[] args) { AbstractList<String> list = new MusicList(); list.add("涼涼"); list.add("奇談"); list.add("紅顏"); list.add("伴虎"); list.add("在人間"); Iterator<String> iterator = list.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
6.運行效果
涼涼 奇談 紅顏 伴虎 在人間
至此一個簡單的迭代器
就完成了,實現了對容器的遍歷。能夠看到迭代器在Client
中遍歷時根本不須要知道他底層的實現,只須要經過迭代器來遍歷就能夠了。
上文介紹了本身實現一個簡單的迭代器
,看完的應該就不陌生了,它其實在JAVA的不少集合類中被普遍應用,接下來看看JAVA源碼中是如何使用迭代器模式的。
List<String> list = new ArrayList<>(); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }
看完這段代碼是否是很熟悉,與咱們上文代碼基本相似
Iterator
接口的具體迭代器對象接下來看下ArrayList
中的iterator
是如何實現的
public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") 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]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
這部分代碼仍是比較簡單,大體就是在iterator
方法中返回了一個實例化的Iterator
對象。Itr是一個內部類,它實現了Iterator
接口並實現了其中的方法。
當咱們在使用JAVA開發的時候,想使用迭代器模式的話,只要讓咱們本身定義的容器類實現java.util.Iterable
並實現其中的iterator方法使其返回一個java.util.Iterator
的實現類就能夠了。
迭代器模式
與集合共生共死的,通常來講,咱們只要實現一個集合,就須要同時提供這個集合的迭代器,就像java中的Collection,List、Set、Map等,這些集合都有本身的迭代器。假如咱們要實現一個這樣的新的容器,固然也須要引入迭代器模式,給咱們的容器實現一個迭代器。但在絕大多數狀況,咱們是不須要本身實現的,基本都內置了
優勢
缺點
全文代碼:https://gitee.com/battcn/design-pattern/tree/master/Chapter14/battcn-iterator
微信公衆號:battcn
(歡迎調戲)
關注公衆號:battcn
,回覆springboot
便可得到 <Spring Boot從入門到實戰 基礎實戰系列教程全集>
與 <2017最新spring boot 外賣實戰微信公衆平臺視頻教程>