Java设计模式----迭代器模式

Java设计模式----迭代器模式

为什么要使用这种设计模式呢?这种设计模式可以提高程序的可复用性,相比for循环更加的灵活,不管集合类怎么改变,只要集合的iterator方法能正确地返回Iterator实例,即使不对while循环做任何修改,也可以正常使用。

这里有一个小建议:不要只使用具体的类来编程,要优先使用抽象类和接口来编程

下面上代码,为了方便理解,使用书与书架的关系编写代码

1.1 创建集合接口
/**
 * 定义返回类型为Iterator的方法
 * @author PeiYP
 * @date 2022年01月14日 23:16
 */
public interface Aggregate {
    public abstract Iterator iterator();
}
1.2 创建迭代器接口
/**
 * 迭代器接口,定义了抽象方法hasNext(),next()
 * @author PeiYP
 * @date 2022年01月14日 23:17
 */
public interface Iterator {
    /**
     * 用于判断集合中是否还有下一个元素
     * @author PeiYP
     * @date 2022/1/14 23:53
     * @return boolean 如果有返回true,如果没有返回false
     */
    public abstract boolean hasNext();
    /**
     * 用于返回集合中的元素
     * @author PeiYP
     * @date 2022/1/14 23:54
     * @return java.lang.Object
     */
    public abstract Object next();
}
1.3 定义Book类,提供构造器和get方法
public class Book {
    private String name;

    public Book(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
1.4 BookShelf 类主要存放书本信息,扮演集合的角色

常规数组写法放在注释里

public class BookShelf implements Aggregate{

    //定义ArrayList类型的集合存放书籍
    private ArrayList<Book> books;

    /**
     * 构造器用于初始化一个ArrayList数组
     * @author PeiYP
     * @date 2022/1/15 0:03
     * @return null
     */
    public BookShelf() {
        this.books = new ArrayList();
    }

    /**
     * 根据下标来获取书本信息
     * 如果使用常规的数组写法,则返回 return books[index]
     * @author PeiYP
     * @date 2022/1/15 0:04
     * @param index 下标
     * @return edu.pyp.iterator.Book
     */
    public Book getBookAt(int index){
        return books.get(index);
    }

    /**
     * 添加书籍
     * 如果使用常规的数组写法,
     * 则在外部定义一个 int 类型的last变量来记录集合的最后一个元素的下标
     * 再将书籍添加到这个位置,最后 last++
     * 写法:this.books[last] = book;
     *      last++;
     * @author PeiYP
     * @date 2022/1/15 0:06
     * @param book
     */
    public void appendBook(Book book){
        this.books.add(book);
    }

    /**
     * 获取集合长度
     * 如果使用常规的数组写法,则返回 last
     * @author PeiYP
     * @date 2022/1/15 0:10
     * @return int
     */
    public int getLength(){
        return books.size();
    }

    /**
     * 重写了接口的方法 返回了一个 BookShelfIterator的实例,
     * 并把集合传入BookShelfIterator的构造器中
     * @author PeiYP
     * @date 2022/1/15 0:11
     * @return edu.pyp.iterator.Iterator
     */
    @Override
    public Iterator iterator() {
        return new BookShelfIterator(this);
    }
}
1.5 创建BookShelfIterator类,实现Iterator接口

这就是一个自定义的迭代器

/**
 * 扮演迭代器的角色
 * 类中定义两个属性为BookShelf类型的对象和记录下标的index
 * @author PeiYP
 * @date 2022年01月14日 23:26
 */
public class BookShelfIterator implements Iterator {

    private BookShelf bookShelf;
    private int index;

    /**
     * 构造器用于初始化,接收BookShelf传来的实例
     * @author PeiYP
     * @date 2022/1/15 0:15
     * @param bookShelf 传入bookShelf对象
     * @return null
     */
    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }

    /**
     * 重写接口方法,判断如果index<集合的长度,就说明还有下一条数据
     * 否则就没有下一条
     * @author PeiYP
     * @date 2022/1/15 0:15
     * @return boolean
     */
    @Override
    public boolean hasNext() {

        if (index < bookShelf.getLength()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 重写接口方法,用于接收书本信息
     * 内部index自增
     * @author PeiYP
     * @date 2022/1/15 0:17
     * @return java.lang.Object
     */
    @Override
    public Object next() {
        Book book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
}

1.6 测试代码
public class RunMain {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf();
        bookShelf.appendBook(new Book("Around the world in 80 days"));
        bookShelf.appendBook(new Book("Bible"));
        bookShelf.appendBook(new Book("Cinderella"));
        bookShelf.appendBook(new Book("Daddy-Long-Legs"));
        bookShelf.appendBook(new Book("Daddy-Long-Legs"));
        bookShelf.appendBook(new Book("Daddy-Long-Legs"));
        Iterator iterator = bookShelf.iterator();
        while (iterator.hasNext()) {
            Book next = (Book) iterator.next();
            System.out.println(next.getName());
        }
    }
}

在测试代码中我们可以看出,不用普通数组的原因是普通数组的数据不能重复,从而可扩展性不强。如果是多线程则建议使用Vector或其他线程安全的集合类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值