Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中为嵌套循环的内部创建迭代器?_Java_Foreach_Iterator_Nested Loops - Fatal编程技术网

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

如何在Java中为嵌套循环的内部创建迭代器?,java,foreach,iterator,nested-loops,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

我可以编写一个嵌套循环来迭代嵌套数组的元素,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();
        }
    }
}
但这种方法的问题是:

  • 在这里,需要一个双嵌套循环来遍历数据结构的事实是显而易见的
  • 我必须为每个需要调用内部元素的函数复制这个嵌套循环
  • 这打破了遍历结构方法的封装。我可能会选择使用其他结构实现嵌套数组,并且不希望将嵌套迭代的每个副本都更改为所需的任何遍历方法
  • 嵌套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_迭代器类

    我的问题是“如何编写Foo_迭代器,跟踪嵌套迭代器的状态?”? 我想它看起来会像下面这样,但我缺少了跟踪状态的信息

    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
    ):

    类FooIterator实现迭代器{ 私有最终迭代器; 私有迭代器内部=null; 公共FooIterator(字符串[][]数据){ outer=Arrays.asList(data.iterator(); nextInner(); } 私有void nextInner(){ if(outer.hasNext()) inner=Arrays.asList(outer.next()).iterator(); } 公共布尔hasNext(){ 返回inner!=null&&inner.hasNext(); } 公共字符串next(){ String next=inner.next(); 如果(!inner.hasNext()) nextInner(); 下一步返回; } 公共空间删除(){ //不用 } } 事实上,我认为跟踪这两个指数没有什么错


    当然,在您的代码中,
    fi
    实际上应该是一个
    Iterable
    (可能是您的超类),它实例化了消费者永远不会看到的
    FooIterator

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

    类FooIterator实现迭代器{ 私有最终迭代器; 私有迭代器内部=null; 公共FooIterator(字符串[][]数据){ outer=Arrays.asList(data.iterator(); nextInner(); } 私有void nextInner(){ if(outer.hasNext()) inner=Arrays.asList(outer.next()).iterator(); } 公共布尔hasNext(){ 返回inner!=null&&inner.hasNext(); } 公共字符串next(){ String next=inner.next(); 如果(!inner.hasNext()) nextInner(); 下一步返回; } 公共空间删除(){ //不用 } } 事实上,我认为跟踪这两个指数没有什么错

    当然,在您的代码中,
    fi
    实际上应该是一个
    Iterable
    (可能是您的超类),它实例化了消费者永远不会看到的
    FooIterator

    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
        }
    }