在jdk中,與迭代器相關的接口有兩個:Iterator 與 Iterable。html
Iterator:迭代器,Iterator及其子類一般是迭代器自己的結構與方法;迭代器是一種模式,它可使得對於序列類型的數據結構的遍歷行爲與被遍歷的對象分離,即咱們無需關心該序列的底層結構是什麼樣子的。只要拿到java
這個對象,使用迭代器就能夠遍歷這個對象的內部。設計模式
Iterable:可迭代的,那些想用到迭代器功能的其它類,如AbstractList HashMap等,須要實現該接口。 數據結構
1)Iteratorapp
Java提供一個專門的迭代器<<interface>>Iterator,咱們能夠對某個序列實現該interface,來提供標準的Java迭代器。Iterator接口實現後的功能是「使用」一個迭代器。ide
Package java.util; public interface Iterator<E> { //判斷是否存在下一個對象元素 boolean hasNext(); //得到下一個元素 E next(); //移除下一個元素 void remove(); }
2)Iterable函數
Java中還提供了一個Iterable接口,Iterable接口實現後的功能是「返回」一個迭代器(Iterator),咱們經常使用的實現了該接口的子接口有: Collection<E>, Deque<E>, List<E>, Queue<E>, Set<E> 等.該接口的iterator()方測試
法返回一個標準的Iterator實現。this
public interface Iterable<T> { Iterator<T> iterator(); }
看完源碼,咱們來看看迭代器是如何使用的: spa
1) 若類A想要使用迭代器,則它的類聲明部分爲 class A implement Iterable
2) 在類A實現中,要實現Iterable接口中的惟一方法:Iterator<T> iterator(); 這個方法用於返回一個迭代器,即Iterator接口及其子類;
3) 在類A中,定義一個內部類S,專門用於實現Iterator接口,定製類A自已的迭代器實現。
以下:
//A實現Iterable接口 class A implement Iterable { //該接口返回一個Iterator對象 Iterator<T> iterator() {...} class S implement Iterator<E> { //上面這個對象會有具體實現的方法 boolean hasNext() {....} E next() {....} void remove() {....} } }
下面咱們來看下抽象類AbstractList的jdk源碼
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // List接口實現了Collection<E>, Iterable<E> protected AbstractList() { } ... // 這裏返回一個迭代器對象 public Iterator<E> iterator() { return new Itr(); } // Itr內部類實現迭代器 private class Itr implements Iterator<E> { int cursor = 0; int lastRet = -1; int expectedModCount = modCount; // 實現hasNext方法 public boolean hasNext() { return cursor != size(); } // 實現next方法 public E next() { //判斷是否有下一個 checkForComodification(); try { E next = get(cursor); lastRet = cursor++; //返回下一個 return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } // 實現remove方法 public void remove() { if (lastRet == -1) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } //判斷是否有下一個方法 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } }
//實現Iterable class ScanAppleStore implements Iterable<String> { ArrayList<String> appleStore = new ArrayList<String>(); //爲初始appleStore賦值 ScanAppleStore() { Collections.addAll(appleStore, "Sweet", "Sour", "Bitter", "litter Sweet", "litter Sour", "litter Bitter"); System.out.print(appleStore); } //重寫Iterator方法 @Override public Iterator<String> iterator() { return new Iterator<String>() { private int i = 0; public boolean hasNext() { if (i < appleStore.size()) { return true; } else { return false; } } public String next() { return appleStore.get(i++); } public void remove() { System.out.print("not defined!"); } }; } public Iterable<String> reverseIterator() { return new Iterable<String>() { public Iterator<String> iterator() { return new Iterator<String>() { private int i = appleStore.size() - 1; public boolean hasNext() { if (i > -1) { return true; } else { return false; } } public String next() { return appleStore.get(i--); } public void remove() { System.out.print("not defined!"); } }; } }; }}
測試類
public class TestIterable { //構造函數初始化 TestIterable() { ScanAppleStore appleTree = new ScanAppleStore(); //採用系統自帶的迭代器 System.out.println("採用系統自帶的迭代器iterator:"); for (String str : appleTree) { System.out.println(str); } System.out.println("======================"); System.out.println("採用本身從新迭代器,讓相反輸出"); //採用本身從新迭代器,讓相反輸出 for (String str : appleTree.reverseIterator()) { System.out.println(str); } } public static void main(String[] args) { TestIterable a = new TestIterable(); } }
運行結果:
[Sweet, Sour, Bitter, litter Sweet, litter Sour, litter Bitter]
採用系統自帶迭代器iterator: Sweet Sour Bitter litter Sweet litter Sour litter Bitter ====================== 採用本身從新迭代器,讓相反輸出: litter Bitter litter Sour litter Sweet Bitter Sour Sweet
GOF給出的定義爲:提供一種方法訪問一個容器(container)對象中各個元素,而又不需暴露該對象的內部細節。
Iterator模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又可以讓外部代碼透明的訪問集合內部的數據。
1) 迭代器角色(Iterator):迭代器角色負責定義訪問和遍歷元素的接口。
2) 具體迭代器角色(Concrete Iterator):具體迭代器角色要實現迭代器接口,並要記錄遍歷中的當前位置。
3) 容器角色(Container):容器角色負責提供建立具體迭代器角色的接口。
4) 具體容器角色(Concrete Container):具體容器角色實現建立具體迭代器角色的接口——這個具體迭代器角色於該容器的結構相關。
1)迭代器角色
public interface Iterator { public Object next(); public boolean hasNext(); }
2)具體迭代器角色
public class ConcreteIterator implements Iterator { private List list = new ArrayList(); private int cursor = 0; public ConcreteIterator(List list) { this.list = list; } @Override public Object next() { Object obj = null; if (this.hasNext()) { obj = this.list.get(cursor++); } return obj; } @Override public boolean hasNext() { if (cursor == list.size()) { return false; } return true; } }
3)容器角色
public interface Aggregate { public void add(Object obj); public void remove(Object obj); public Iterator iterator(); }
4) 具體容器角色
public class ConcreteAggregate implements Aggregate { private List list = new ArrayList(); @Override public void add(Object obj) { list.add(obj); } @Override public void remove(Object obj) { list.remove(obj); } @Override public Iterator iterator() { return new ConcreteIterator(list); } }
測試類
public class Client { public static void main(String[] args) { Aggregate ag = new ConcreteAggregate(); ag.add("小明"); ag.add("小紅"); ag.add("小剛"); Iterator it = ag.iterator(); while (it.hasNext()) { String str = (String) it.next(); System.out.println(str); } }}
運行結果
小明 小紅 小剛
優勢:
1)它支持以不一樣的方式遍歷一個聚合對象。
2)迭代器簡化了聚合類。
3)在同一個聚合上能夠有多個遍歷。
4)在迭代器模式中,增長新的聚合類和迭代器類都很方便,無須修改原有代碼。
缺點:
因爲迭代器模式將存儲數據和遍歷數據的職責分離,增長新的聚合類須要對應增長新的迭代器類,類的個數成對增長,這在必定程度上增長了系統的複雜性。
其實這整篇文章幾乎都來自該篇文章,用參考都不太好意思,哈哈。
想太多,作太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多作。中校【7】