【问题标题】:Iterate through a 2D array as if it were a 1D array using Iterator使用 Iterator 遍历 2D 数组,就好像它是 1D 数组一样
【发布时间】:2017-06-21 15:33:22
【问题描述】:

我是 Java 初学者,我必须从 Iterator<Iterator<Integer>> 之类的东西中获取值。例如,我们可能有:

{{1, 2}, {3, 4}, {5, 6}}

next() 的结果应该是1。如果我们再尝试一次next() - 2,然后 - 34 等。就像从一维数组中一一获取值,但从二维数组获取值。我们不应该不复制任何东西。所以,我在下面写了一些糟糕的代码:

public class IteratorNext {

    private Iterator<Iterator<Integer>> values = null;
    private Iterator<Integer> current;

    public IteratorNext(Iterator<Iterator<Integer>> iterator) {
        this.values = iterator;
    }

    public int next() throws NoSuchElementException {
        current = values.next();
        if (!current.hasNext()) {
            values.next();
        }
        if (!values.hasNext() && !current.hasNext()) {
            throw new NoSuchElementException("Reached end");
        }
        return current.next();
    }
}

该代码不正确,因为next() 的结果是1,然后是3,然后是5,并且因为这里有异常。如何解决这个问题?

【问题讨论】:

  • 你在使用java-8吗?那么有一种更简单的方法可以做到这一点。

标签: java arrays multidimensional-array iterator


【解决方案1】:

如果您使用的是Java-8,您可以利用flatMapToInt 函数将您的二维数组转换为一维数组(可以假设array2d 是对你的二维数组):

Arrays.stream(array2d).flatMapToInt(Arrays::stream).forEach(System.out::println);

如果你想坚持你的解决方案,你需要修改你的next方法如下:

public int next() throws NoSuchElementException {
    int result = -1;
    //Are we already iterating one of the second dimensions?
    if(current!=null && current.hasNext()) {
        //get the next element from the second dimension.
        result =  current.next();
    } else if(values != null && values.hasNext()) {
        //get the next second dimension
        current = values.next();
        if (current.hasNext()) {
            //get the next element from the second dimension
            result =  current.next();
        } 
    } else {
        //we have iterated all the second dimensions
        throw new NoSuchElementException("Reached end");
    }

    return result;

}

【讨论】:

    【解决方案2】:
    public static class IteratorNext {
    
        private Iterator<Iterator<Integer>> values = null;
        private Iterator<Integer> current;
    
        public IteratorNext(Iterator<Iterator<Integer>> iterator) {
            this.values = iterator;
        }
    
        public int next() throws NoSuchElementException {
    
            if (current != null && current.hasNext()) {
                Integer val = current.next();
                return val;
            }
    
            if (values != null && values.hasNext()) {
                current = values.next();
                if (current != null && current.hasNext()) {
                    Integer val = current.next();
                    return val;
                }
            }
    
            throw new NoSuchElementException("Reached end");
    
        }
    }
    

    【讨论】:

    • null 检查第三个if 条件中的current 并不是真正需要的,因为current 代表一个永远不可能是nullIterator
    • 如果您能解释一下您的修改,那就太好了。
    【解决方案3】:

    每次调用next(),都要处理结果。

    next() 方法的第一行跳过了第一个元素,因为您在 next() 方法的末尾调用 current.next()。

    更一般地说,这段代码不是处理集合的正确方法。你得从使用的角度来分析问题。

    【讨论】:

      【解决方案4】:

      问题是每次调用 next() 时都以

       current = values.next();
      

      因此,在每次调用时,您都会跳到下一个迭代器,而不是尝试在当前迭代器上继续迭代。

      相反,您应该做类似的事情

      if(!current.hasNext())
         current = values.next();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-21
        • 2020-06-12
        • 2018-04-08
        • 2017-03-04
        • 2017-06-18
        相关资源
        最近更新 更多