Java提供了 foreach (enhanced for) 的循环简写语法:

ArrayMap<String, Integer> am = new ArrayMap<String, Integer>();

for (String s : am) {
    System.out.println(s);
}

实现的关键原理是使用Iterable接口使一个类变成可迭代的: 该接口包含一个iterator()方法用于返回一个Iterator对象。Iterator接口定义Iterator对象和hasNext(), next()方法来进行实际的迭代操作。

public class ArrayMap<K, V> implements Map61B<K, V>, Iterable<K> {
    private K[] keys;
    private V[] values;
    int size;

    public ArrayMap() {
        keys = (K[]) new Object[100];
        values = (V[]) new Object[100];
        size = 0;
     }

    @Override
    public Iterator<T> iterator() {
        return new KeyIterator();
    }

    public class KeyIterator implements Iterator<K> {
        private int ptr;
        public KeyIterator() { ptr = 0; }
        public boolean hasNext() { return (ptr != size); }
        public K next() {
            K returnItem = keys[ptr];
            ptr = ptr + 1;
            return returnItem;
        }
    }
}

不同的数据结构,Iterator有不同的实现方式.

KeyIterator即使是private也可以编译, 因为iterator()在这里是public的:

import java.util.Iterator;

public class Demo{
    public static void main(String[] args) {
        ArrayMap<String, Integer> am = new ArrayMap<String, Integer>();

        Iterator<String> it = am.iterator();

        for (String s : am) { ... }
    }1
}

除了用嵌套类来自定义实现Iterator, 也可以利用数据结构本身的特性. 比如ArrayMap里面刚好包含一个可迭代的数据结构List keys

public Iterator<T> iterator() {
    List<K> keylist = keys();
    return keylist.Iterator();
}

注意要点

  • hasNext()的判断依据是当前状态下能返回至少一个成员, 不要混淆为下一次能否返回: 因为迭代时过程中, 每次调用next()之前, java 都会先调用hasNext().
  • 实现方法时, 要保证第一次next()返回的是第一个成员.