1.设计模式——迭代器模式

66 阅读2分钟

Itertor

1.迭代器简介

迭代器模式,也是我们所熟知的Itertor,给集合遍历的一个重要工具,指的是一个一个遍历。

传统的方式,我们可以使用for循环对一个集合进行遍历。

List<String> list = new ArrayList<>();
​
        for (int i = 0; i < 100; i++) {
            list.add(i + " 次增加");
        }
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
​
        }

i++的作用就实现一次递增。那么Itertor就是将这里的i进行抽象化,设计成一种类似循环的模式,将一件事反复去做,这就是迭代器。

2.Itertor源码

我们可以点进去Itertor的源码中,这是在java.util包下的类:

public interface Iterator<E> {
  
    boolean hasNext();
​
    E next();
​
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}
​

这里省略了注释,next表示返回当前的值,并将指针指向下一位。hasNext是判断是否可以指向下一位。因为index从0开始,而判断是从1开始的。所以可以遍历出集合内部的元素。相对的,这个迭代器的好处就是不需要用户知道当前上下文和集合对象的大小,都可以准确的去遍历出来,当然在遍历的同时不可以对集合做修改操作。

理解这段话,当然可以用下面的这个代码去实现:

 public static void main(String[] args) {
        List list = new ArrayList();
        list.add(11);
        list.add(22);
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println( iterator.hasNext());
            System.out.println(iterator.next());
            System.out.println( iterator.hasNext());
        }
​
    }

运行结果:

image-20220516103208189.png

根据运行结果,可以看出,当执行最后一次.next方法之后,可以看出当前指针已经越界了,那么最后打印的.hasNext方法自然false,程序退出。

3.BookShelf

这里为了方便理解,我们引出一个取书的案例。

名字说明
Aggregate表示集合的接口
Itertor迭代器遍历集合的接口【java.util包下】
Book表示书的集合
Bookshelf表示书架的类
BookShelfItertorItertor遍历书架的类
BookMain测试程序
public interface Aggragate {
    /**
     * @return 无
     */
    public abstract Iterator iterator();
}
public class Book {
    private String name;
​
    public Book(String name) {
        this.name = name;
    }
​
    public String getName() {
        return name;
    }
}
public class BookShelf implements Aggragate {
​
    private Book[] books;
​
    private int last = 0;
​
    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 last;
    }
​
    @Override
    public Iterator iterator() {
        return new BookShelfIterator(this);
    }
}
​
public class BookShelfIterator implements Iterator {
​
    private BookShelf bookShelf;
    private int index;
​
    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }
​
    @Override
    public boolean hasNext() {
        if (index < bookShelf.getLength()){
            return true;
        }
        return false;
    }
​
    @Override
    public Object next() {
        Book book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
}
public class BookMains {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("java"));
        bookShelf.appendBook(new Book("Python"));
        bookShelf.appendBook(new Book("json"));
        bookShelf.appendBook(new Book("mysql"));
        Iterator iterator = bookShelf.iterator();
        while (iterator.hasNext()) {
            Book book = (Book) iterator.next();
            System.out.println(book.getName());
        }
    }
}

测试结果:

image-20220516133052035.png

代码里面具体讲述了迭代器的运行流程,其实迭代器是不去依赖于对象本身的,无论对象的内容是什么,只要对象可以实现迭代器,就可以使用迭代器,通过这种方式,将对象内容打印出来。