什么是迭代器模式?
迭代器模式是一种行为设计模式,让你能在不暴露集合底层表现形式 (列表、栈和树等) 的情况下遍历集合中所有的元素。
迭代器模式的主要思想是将集合的遍历行为抽取为单独的迭代器对象。
Iterable接口
package java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
/**
* 可迭代接口
*/
public interface Iterable<T> {
/**
* 返回类型为T的迭代器
*/
Iterator<T> iterator();
/**
* 迭代元素,执行消费器的accept方法
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
/**
* 创建返回类型为T的可分割迭代器
*/
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
Iterator接口
package java.util;
import java.util.function.Consumer;
/**
* 迭代器接口
*/
public interface Iterator<E> {
/**
* 如果有下一个元素,则返回true
*/
boolean hasNext();
/**
* 返回迭代器的下一个元素
*/
E next();
/**
* 删除迭代器上次返回的元素
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* 对剩下的元素执行给定消费器的accept方法
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
例子
Book类
/**
* 书类
*/
public class Book {
private Integer id;
private String name;
private String author;
public Book(Integer id, String name, String author) {
this.id = id;
this.name = name;
this.author = author;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getAuthor() {
return author;
}
}
BookShelf类
import java.util.Iterator;
/**
* 书架类
*/
public class BookShelf implements Iterable{
private Book[] books;
private int len = 0;
/**
* 设置书架最大值
* @param maxSize
*/
public BookShelf(int maxSize){
this.books = new Book[maxSize];
}
/**
* 获取指定下标位置的书
*/
public Book getBookAt(int index){
return books[index];
}
/**
* 添加书
*/
public void appendBook(Book book){
this.books[len] = book;
len++;
}
/**
* 获取现有书的数量
*/
public int getLength(){
return len;
}
/**
* 获取迭代器
*/
@Override
public Iterator<Book> iterator() {
return new BookIterator(this);
}
}
BookIterator类
import java.util.Iterator;
/**
* 书架迭代器类
*/
public class BookIterator implements Iterator {
private BookShelf bookShelf;
private int index;
public BookIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < bookShelf.getLength() ? true : false;
}
@Override
public Object next() {
return bookShelf.getBookAt(index++);
}
}
Main
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
Book b1 = new Book(1,"安徒生童话","安徒生");
Book b2 = new Book(2,"福尔摩斯探案集","柯南·道尔");
Book b3 = new Book(3,"图解设计模式","结城浩");
BookShelf bookShelf = new BookShelf(10);
bookShelf.appendBook(b1);
bookShelf.appendBook(b2);
bookShelf.appendBook(b3);
// for循环遍历
for(int i = 0;i<bookShelf.getLength();i++){
Book book = bookShelf.getBookAt(i);
System.out.println("id:"+book.getId()+"\nname:"+book.getName()+"\nauthor:"+book.getAuthor()+'\n');
}
System.out.println("****************************************\n");
//迭代器遍历
Iterator<Book> iterator = bookShelf.iterator();
while(iterator.hasNext()){
Book book = iterator.next();
System.out.println("id:"+book.getId()+"\nname:"+book.getName()+"\nauthor:"+book.getAuthor()+'\n');
}
}
}
结果
总结
Iterator模式常用于遍历集合,它允许集合提供一个统一的Iterator接口来遍历元素,同时保证调用者对集合内部的数据结构一无所知,从而使得调用者总是以相同的接口遍历各种不同类型的集合。