简体   繁体   中英

Iterate through a 2D array as if it were a 1D array using Iterator

I'm a beginner in Java and I have to recieve values from such thing as Iterator<Iterator<Integer>> . For example, we may have:

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

The result of next() should be 1 . If we try next() one more time - 2 , then - 3 , 4 , etc. Like getting values from 1D array one by one, but from 2D array. We should not copy anything. So, I wrote some bad code below:

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();
    }
}

That code is not correct, because result of next() is 1 , then 3 , then 5 and because of exception here. How to fix this?

If you are using Java-8 , you can take advantage of the flatMapToInt function to iron out your 2D array into a 1D array ( array2d can be assumed to be a reference to your 2D array) :

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

if you want to stick to your solution, you need to modify your next method as follows :

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;

}
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");

    }
}

Each time you call next(), you have to deal with the result.

The first line of your next() method you skip the first element because you recall current.next() at the end of your next() method.

More generally speaking this code is not the right way to deal with collections. You have to analyze the problem in term of usage.

The problem is that each time you call next() you start with

 current = values.next();

So at each call you skip to the next iterator, without trying to continue iteration on current.

Instead you should do something like

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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