java - 如何在 Java 中的嵌套循环内部创建迭代器?

标签 java foreach iterator nested-loops

我可以编写一个嵌套循环来迭代嵌套数组的元素,for-each 优雅地隐藏了嵌套数组每一层的遍历细节:

Foo[][] dbl_array;
public void do_all() {
    // Iterate over both levels of a nested array, invoking "bar" on each inner element.
    for (final Foo[] arr_1d : dbl_array) {
        for (final Foo el : arr_1d) {
            el.bar();
        }
    }
}

但是这种方法的问题是:

  1. 需要双重嵌套循环来遍历数据结构的事实在这里非常明显。
  2. 我必须为需要在内部元素上调用的每个函数复制此嵌套循环。
  3. 这破坏了遍历结构的方法的封装。我可能会选择使用其他结构来实现嵌套数组,并且不想将嵌套迭代的每个副本更改为所需的任何遍历方法。
  4. 嵌套的 for-each 循环的结构完全符合需要。迭代器不应在嵌套内进行所需的函数调用,而应在内部处理数据结构遍历,公开遍历期间遇到的每个条目。

那么...我该如何更改它,以便实现一个可以调用的迭代器,如下所示:

Foo_Iterator fi = Foo.iterator();
for (final Foo el : fi) { // The Iterator hides the traversal details from the caller.
    el.bar();             // The desired function is invoked on each element encountered.
}

这会将如何完成迭代的详细信息留给 Foo_Iterator 类。

我的问题是“如何编写 Foo_Iterator,跟踪嵌套迭代器的状态? 我认为它看起来像下面这样,但我缺少跟踪状态的位。

class Foo_Iterator extends Whiz implements Iterator {
    public Foo_Iterator() {
        // Initialize state based on access to the superclass Whiz.
    }
    public boolean hasNext() {
        // Is there an elegant way to save the state of both iterators between each call to hasNext() and next()?
        // The "inelegant" way would be to keep track of the inner and out array indices,
        // comparing the current index to the array length...
    }
    public Foo next() {
        // Access the "next" in the nested sequence.
    }
    public void remove() {
        // I probably won't implement or need/use this one.
    }
}

关于如何以“优雅”的方式做到这一点有什么建议吗?

谢谢。

最佳答案

不确定这是否更优雅,但您也可以使用迭代器来跟踪状态(使用String作为示例):

class FooIterator implements Iterator<String> {

    private final Iterator<String[]> outer;
    private Iterator<String> inner = null;

    public FooIterator(String[][] data) {
        outer = Arrays.asList(data).iterator();
        nextInner();
    }

    private void nextInner() {
        if (outer.hasNext())
            inner = Arrays.asList(outer.next()).iterator();
    }

    public boolean hasNext() {
        return inner != null && inner.hasNext();
    }

    public String next() {
        String next = inner.next();
        if (!inner.hasNext())
            nextInner();
        return next;
    }

    public void remove() {
        // not used
    }
}

实际上,我认为跟踪这两个指数没有什么问题。

当然,在您的代码中 fi 实际上应该是一个 Iterable(大概是您的父类(super class)),它实例化 FooIterator,而消费者永远不应该看到它。

关于java - 如何在 Java 中的嵌套循环内部创建迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9678801/

相关文章:

java - Google map : input Lat and Long and receive images, 信息、名称等

java - 如何在 Android 的 Expandablelistview 中处理子点击事件?

c# - 如何 "reset"C# SqlCommand 对象,以便我可以在循环中重新使用它

python - 如何以更优雅的 Pythonic 方式组织此循环

c++ - 遍历动态 vector 时 auto 的异常行为

java - weblogic 12 中的 EJB 初始化错误,但 10 中没有

arrays - AP计算机科学: ArrayList Multiple Choice

c# - foreach 中的 Excel Interop CustomDocumentProperties 导致挂起

java - 如何使用 Java 8 增强 List 方法中的重复对象?列表中的对象是嵌套的,这就是使这个复杂的原因

c++ - STL 算法将整个容器而不是 .begin(), end() 作为 arg?