为什么for-each循环不接受Iterable类的实例?

时间:2015-05-04 06:59:57

标签: java

Iterable<Position<Integer>> iterable = list.positions();
    Iterator<Position<Integer>> iter = iterable.iterator();

    while (iter.hasNext()) {
        System.out.println(iter.next().getData());
    }

以上代码没有任何问题。 list只是我编写的List类的一个实例。它包含Integer类型的元素。

        for (Position<Integer> pos : iterable) {

    }

此代码在冒号后面的部分失败。这应该等同于第一段代码,即带有while循环的代码。所以我不明白为什么for-each循环有错误。错误说:“只能遍历数组或java.lang.Iterable的实例” - 但iterable已经是Iterable,不是吗?我在这里缺少什么?

以下是实现上述方法和类型的完整代码。

    private class PositionIterator implements Iterator<Position<E>> {
    private Position<E> cursor = first();
    private Position<E> current = null;

    public boolean hasNext() {
        return cursor.getData() != null;
    }

    public Position<E> next() {
        if (cursor == null) throw new NoSuchElementException("reached the end of the list");
        current = cursor;
        cursor = after(cursor);
        return current;
    }
}

private class PositionIterable implements Iterable<Position<E>> {
    public Iterator<Position<E>> iterator() {
        return new PositionIterator();
    }
}

public Iterable<Position<E>> positions() {
    return new PositionIterable();
}

这些是另一个名为PositionalList<E>的类中的嵌套类。为了保持这篇文章的紧凑性,我决定省略外面的课程。它只是一堆getter和setter方法,对于List类来说是典型的。

public interface Iterable<E> {
    public Iterator<E> iterator();
}

^这是由PositionIterable

实现的Iterable接口
public interface Iterator<E> {
    boolean hasNext();
    E next();
}

^那就是Iterator界面。

2 个答案:

答案 0 :(得分:6)

增强型for循环接受Iterable,而不是IteratoriterIterator

因此:

for (Position<Integer> pos : iter)

应该是:

for (Position<Integer> pos : iterable)

编辑:根据评论,您的问题必须通过自定义java.lang.Iterable界面隐藏Iterable。如果您的iterable变量属于自定义Iterable界面的类型,则增强型for循环无法使用该变量,该循环接受java.lang.Iterable

答案 1 :(得分:4)

运行该代码不应该有任何问题。这是我当地的测试代码

public static void main(String[] args)
{
    Iterable<String> iterable = Arrays.asList("foo",
                                              "bar");
    for (String anIterable : iterable)
    {
        System.out.println(anIterable);
    }
}

如果你创建了一个名为Iterable的本地类或接口,这是我能想到为什么这样做不起作用的唯一原因。如果您已经这样做,请删除它,然后可以返回并查看接口的用途。