迭代器模式(Iterator)用於在數據集合中按照順序遍歷集合,在遍歷的同時不須要暴露對象的內部表示,根據不一樣的需求咱們能夠採用不一樣的方式遍歷集合,它主要解決三個問題 一、可以遍歷一個集合對象。二、咱們不須要了解集合對象的內部結構。三、可以提供多種不一樣的遍歷方式。javascript
迭代器模式是與集合共生共死的,通常來講,咱們只要實現一個集合,就須要同時提供這個集合的迭代器,就像java中的Collection,List、Set、Map等,這些集合都有本身的迭代器。假如咱們要實現一個這樣的新的容器,固然也須要引入迭代器模式,給咱們的容器實現一個迭代器。引自java
接下來就經過示例程序進行迭代器的學習。git
這段程序的目的就是將書(Book)放到書架(BookShelf)中,並將書的名字按順序顯示出來。若是你對類圖不熟悉可移步 Java利器之UML類圖詳解程序員
Aggregate 接口是所須要遍歷集合的接口,有一個iterator方法,該方法返回一個用於遍歷集合的迭代器,即建立出按順序訪問保存在我內部元素的對象。github
public interface Aggregate {
public abstract Iterator iterator();
}複製代碼
當想要遍歷集合中元素時,能夠調用iterator方法來生成一個實現了Iterator接口的類的實例。對於Iterator接口就是遍歷集合元素的,相似於for循環,在此該接口簡單實現爲設計模式
public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}複製代碼
對於這兩個方法應該很常見,hasNext()返回布爾類型表示是否有下一個元素,存在下一個元素就返回true,不然返回false,返回false時也就表示該集合元素已所有被遍歷,也是終止條件。next方法返回的就是集合中的當前指向元素,而且將迭代器指向下一個元素,而這些操做,都是Iterator的實現類中處理的。數組
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
}複製代碼
該類就是表示書架的類,該類有一個數組books用於存放書籍,並提供了獲取數據,添加書籍及書籍數量的方法,因爲實現了Aggregate接口,則需重寫iterator方法,該方法返回BookShelfIterator類的實例做爲該類的iterator。當外部想要遍歷書架時就調用這個方法。性能優化
public class BookShelf implements Aggregate {
private Book[] books;
private int last;
public BookShelf(int maxsize) {
this.books = new Book[maxsize];
}
public Book getBookAt(int index) {
return books[index];
}
public void appendBook(Book book) {
this.books[last] = book;
last++;
}
public int getLength() {
return books.length;
}
@Override
public Iterator iterator() {
return new BookShelfIterator(this);
}
}複製代碼
該類是具體的迭代器,實現了Iterator 接口,是迭代器的具體實現,它包含了遍歷集合所必要的信息,bookShelf表示要遍歷的書架,index表示當前迭代器所指向書籍的下標,構造方法接收要遍歷的書架,並將index初始化爲0,hasNext方法是實現接口Iterator的方法,當index小於書架書的長度時表示有下一個數據,不然沒有返回false.next方法就是返回當前所指向的書籍,並將index加一指向下一本書,在這裏至關於for循環中i++.讓循環變量指向下一個元素。app
public class BookShelfIterator implements Iterator {
private int index;
private BookShelf bookShelf;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hasNext() {
if (index < bookShelf.getLength()) {
return true;
} else {
return false;
}
}
@Override
public Object next() {
Book book=bookShelf.getBookAt(index);
index++;
return book;
}
}複製代碼
至此迭代器以及實現完畢了,接下來寫測試類進行書架裝書和遍歷。ide
public class Main {
public static void main(String[] args) {
BookShelf bookShelf=new BookShelf(4);
bookShelf.appendBook(new Book("圖解設計模式"));
bookShelf.appendBook(new Book("將來簡史"));
bookShelf.appendBook(new Book("Android性能優化"));
bookShelf.appendBook(new Book("程序員修煉之道"));
Iterator iterator=bookShelf.iterator();
while (iterator.hasNext()) {
Book book = (Book) iterator.next();
System.out.println(book.getName());
}
}
}複製代碼
輸出信息
圖解設計模式
將來簡史
Android性能優化
程序員修煉之道複製代碼
說了這麼多,也許你會疑問爲何引入Iterator這種複雜的設計模式呢?若是是數組,直接for循環遍歷就能夠了。
固然引入迭代器模式最重要的理由是它能夠將遍歷和實現分離開來,在示例程序中
while (iterator.hasNext()) {
Book book = (Book) iterator.next();
System.out.println(book.getName());
}複製代碼
它只使用了Iterator的hasNext和next方法,並無調用BookShelf的方法,也就是說這裏的循環並不依賴於BookShelf的實現。若是BookShelf開發者想放棄數組,用Vector取而代之,會如何?無論如何變化只要它能生成Iterator實例,即便不對while循環作修改,依然能保證程序正常運行。
在示例程序中,只是簡單的實現從前到後遍歷,固然也能夠是其餘方式,如從後向前,以及跳躍式遍歷。
好了,關於迭代器模式到這裏已經介紹完畢了。有問題歡迎留言指出,Have a wonderful day .
如需文章中所寫代碼,請移步GitHub查看