reupe

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

遍历元素在编程中十分常用,毋庸置疑只要是一个容器,都应该提供遍历其内部元素的方式,这就是本文介绍的迭代器模式。


1.迭代器模式

迭代器模式(Iterator pattern) 提供一个迭代器,它可以按顺序遍历并访问容器中的元素,而无需暴露迭代器的内部实现。

迭代器模式如此常用,以至于Java标准库中,已经在各个容器类中集成了获取迭代器的方法,iterator(),我们使用List的时候根本无需自己去实现迭代器。

但是还是时候需要根据自己的算法来访问元素,比如按照某种递增的规律,某种顺序等等,这样,你就需要自己实现迭代器了。

迭代器模式UML类图如下所示:

一般实现步骤如下:

  1. 定义一个容器类,添加一个可以获取Iterator的方法,比如iterator();
  2. 设计Iterator类, 封装遍历容器元素的算法;
  3. 客户端调用容器的iterator()方法获取该容器的迭代器iterator;
  4. 客户端使用itreator的first(), next(), hasNext()等方法访问元素。

 

Java中,已经给我们提供了一个迭代器的接口Iterator<E>, 通过实现它可以定义自己的迭代器;同时,Java提供了一个Iterable<T>接口,容器实现Iterable接口的iterator()方法可获取相应的迭代器。

 


 

2. 代码实现

下面我定义一个容器实现Iterable接口,通过iterator方法获取迭代器,实现对fibonacci数列的遍历。

 

Iterable接口就相当于UML类图中的TraversalAbstraction, Fibonacci相当于Collection, 实现Iterable,并提供获取iterator的方法。

/**
 * Fibonacci 数列的"容器",通过构造器传入整数值设置该对象保存多少个数。
 * JDK提供了现成的Iterable接口,实现该接口即可获取Fibonacci对象的迭代器。
 */
class Fibonacci implements Iterable<Integer> {

    /** 需要取多少数字 */
    private final int count;

    public Fibonacci(int count) {
        this.count = count;
    }

    private int fib(int n) {
        if (n <= 2) {
            return 1;
        }
        return fib(n - 2) + fib(n - 1);
    }

    /** 根据该方法获取迭代器 */
    @Override
    public Iterator<Integer> iterator() {
        // 使用匿名内部类实现自己的遍历算法
        return new Iterator<Integer>() {
            int n = 1;
            int total = count;

            @Override
            public boolean hasNext() {
                return total > 0;
            }

            @Override
            public Integer next() {
                if (total-- > 0) {
                    return fib(n++);
                }
                throw new RuntimeException("no more!");
            }
        };
    }
}

 

构造元素数量为6的斐波那契数列,并获取其迭代器iterator遍历各个元素

public class IteratorDemo {
    public static void main(String[] args) {
        Fibonacci fibonacci = new Fibonacci(6);
        Iterator<Integer> iterator = fibonacci.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

 

输出结果

1
1
2
3
5
8

 

posted on 2019-03-23 13:21  yxlaisj  阅读(243)  评论(0编辑  收藏  举报