迭代器模式(Iterator)用於在資料集合中按照順序遍歷集合,在遍歷的同時不需要暴露物件的內部表示,根據不同的需求我們可以採用不同的方式遍歷集合,它主要解決三個問題 1、能夠遍歷一個集合物件。2、我們不需要了解集合物件的內部結構。3、能夠提供多種不同的遍歷方式。
迭代器模式的適用場景
迭代器模式是與集合共生共死的,一般來說,我們只要實現一個集合,就需要同時提供這個集合的迭代器,就像java中的Collection,List、Set、Map等,這些集合都有自己的迭代器。假如我們要實現一個這樣的新的容器,當然也需要引入迭代器模式,給我們的容器實現一個迭代器。引自
接下來就通過示例程式進行迭代器的學習。
UML類圖
這段程式的目的就是將書(Book)放到書架(BookShelf)中,並將書的名字按順序顯示出來。如果你對類圖不熟悉可移步 Java利器之UML類圖詳解
介面
Aggregate 介面是所需要遍歷集合的介面,有一個iterator方法,該方法返回一個用於遍歷集合的迭代器,即建立出按順序訪問儲存在我內部元素的物件。
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的實現類中處理的。
Book類
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
}複製程式碼
BookShelf
該類就是表示書架的類,該類有一個陣列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);
}
}複製程式碼
BookShelfIterator
該類是具體的迭代器,實現了Iterator 介面,是迭代器的具體實現,它包含了遍歷集合所必要的資訊,bookShelf表示要遍歷的書架,index表示當前迭代器所指向書籍的下標,構造方法接收要遍歷的書架,並將index初始化為0,hasNext方法是實現介面Iterator的方法,當index小於書架書的長度時表示有下一個資料,否則沒有返回false.next方法就是返回當前所指向的書籍,並將index加一指向下一本書,在這裡相當於for迴圈中i++.讓迴圈變數指向下一個元素。
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;
}
}複製程式碼
至此迭代器以及實現完畢了,接下來寫測試類進行書架裝書和遍歷。
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檢視