博客原文地址:折騰Java設計模式之迭代器模式html
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.java
提供一種不公示其底層細節(結構)的狀況下能順序訪問聚合對象元素的方法。git
其實在java體系中,jdk已經引入了迭代器接口以及對於的容器接口等。就拿迭代器中的角色,在java中找出其對應的類。github
(1)迭代器角色(Iterator):定義遍歷元素所須要的方法,通常來講會有這麼三個方法:取得下一個元素的方法next(),判斷是否遍歷結束的方法hasNext()),移出當前對象的方法remove(),算法
(2)具體迭代器角色(Concrete Iterator):實現迭代器接口中定義的方法,完成集合的迭代。設計模式
(3)容器角色(Aggregate): 通常是一個接口,提供一個iterator()方法,例如java中的Collection接口,List接口,Set接口等數組
(4)具體容器角色(ConcreteAggregate):就是抽象容器的具體實現類,好比List接口的有序列表實現ArrayList,List接口的鏈表實現LinkList,Set接口的哈希列表的實現HashSet等。微信
單獨舉出ArrayList的角色,ide
迭代器角色對應java中的java.lang.Iterator,這個迭代器是java容器公用的。性能
容器角色對應java.lang.Iterable,其還有Iterator iterator()方法獲取迭代器。
具體迭代器角色對應java.lang.ArrayList.Itr,實現了對應的hasNext、next、remove方法。
具體容器角色那就是java.lang.ArrayList了,實現iterator方法返回Itr具體迭代器,用遊標形式實現。
項目中很簡單的實現了一個容器和迭代器。大體參考了ArrayList實現,可是是簡潔版本,去除不少無關以及性能上的東西,只保留最基本的迭代器元素。
@Slf4j
public class Application {
public static void main(String[] args) {
Aggregate<Integer> aggregate = new ConcreteAggregate<>();
aggregate.add(1);
aggregate.add(2);
aggregate.add(3);
aggregate.add(4);
Iterator<Integer> iterator = aggregate.iterator();
while (iterator.hasNext()) {
log.info("循環數據{}", iterator.next());
}
}
}
複製代碼
執行結果以下
簡單的迭代器定義
public interface Iterator<E> {
boolean hasNext();
E next();
}
複製代碼
簡單容器定義
public interface Aggregate<T> {
Iterator<T> iterator();
void add(T t);
}
複製代碼
具體容器和具體的迭代器定義
public class ConcreteAggregate<E> implements Aggregate<E> {
private Object[] elements;
private int size = 0;
public ConcreteAggregate() {
elements = new Object[16];
}
public int getSize() {
return size;
}
public void add(E e) {
elements[size++] = e;
}
@Override
public Iterator<E> iterator() {
return new ConcreteIterator<E>();
}
private class ConcreteIterator<E> implements Iterator<E> {
int cursor;
@Override
public boolean hasNext() {
return cursor != size;
}
@Override
public E next() {
if (cursor >= size) {
return null;
}
return (E) elements[cursor++];
}
}
}
複製代碼
具體容器中用數組來做爲容器來存儲元素,並且最簡單的容器,固定了大小,並無實現擴容的算法等等,只是一個簡單的樣例,可是大部分上,都是直接使用java帶有的迭代器。
因爲迭代器模式將存儲數據和遍歷數據的職責分離,增長新的聚合類須要對應增長新的迭代器類,類的個數成對增長,這在必定程度上增長了系統的複雜性。
對於比較簡單的遍歷(像數組或者有序列表),使用迭代器方式遍歷較爲繁瑣,你們可能都有感受,像ArrayList,咱們寧肯願意使用for循環和get方法來遍歷集合。
迭代器模式是與集合共生共死的,通常來講,咱們只要實現一個集合,就須要同時提供這個集合的迭代器,就像java中的Collection,List、Set、Map等,這些集合都有本身的迭代器。假如咱們要實現一個這樣的新的容器,固然也須要引入迭代器模式,給咱們的容器實現一個迭代器。