繁体   English   中英

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

[英]How do I create an iterator for the inside of a nested loop in Java?

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

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循环的结构从需要的内到外。 迭代器应该在内部处理数据结构遍历,而不是在嵌套内部调用所需的函数,从而公开遍历过程中遇到的每个条目。

所以...如何更改此设置,以便实现可以调用的Iterator,如下所示:

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 (可能是您的超类),该实例化FooIterator ,而消费者则永远不会看到它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM