2

I'm currently trying to set up a custom Iterator method for a 2-dimensional array.

E.g. if the array is {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} the next()-method should return successively with every call 1, 2, 3, 4, 5, 6, 7, 8, 9.

My idea was something like this:

public Iterator<Type> iterator() {
    return new Iterator<Type>() {
        private int currentRow = 0;
        private int currentColumn = 0;

        public boolean hasNext() {
            return currentRow < array.length;
        }

        public Type next() {
            if(currentColumn + 1 == array[0].length){
                currentColumn = 0;
                currentRow ++;
            }
            return array[currentRow][currentColumn++];
        }
    }
}

But it doesn't output the items in the right order and sometimes it even returns null.

2
  • Verify that the array contains what you think it contains. Either look at it in a debugger, or write it to stdout using other iteration. Also, have a look at the contract for Iterator. Your next method should throw NoSuchElementException if it's called when there is no next element. Also, for robustness and generality, consider checking array[currentRow].length rather than array[0].length. Commented Mar 30, 2019 at 12:38
  • The Arrays class's deepToString method will format 2D array for printing. hasNext should also test the currentColumn value Commented Mar 30, 2019 at 13:16

1 Answer 1

2

One possible solution:

public Iterator<Type> iterator() {
    return new Iterator<Type>() {
        private int currentRow = 0;
        private int currentColumn = 0;

        public boolean hasNext() {
            if (currentRow + 1 == array.length) {
                return currentColumn < array[currentRow].length;
            }
            return currentRow < array.length;
        }

        public Type next() {
            if (currentColumn == array[currentRow].length) {
                currentColumn = 0;
                currentRow++;
            }
            if (currentRow == array.length -1 && currentColumn == array[currentRow].length - 1) {
                throw new NoSuchElementException();
            }
            return array[currentRow][currentColumn++];
        }
    };
}

Alternatively you can use Java Streams:

public Iterator<Type> iterator() {
    return Arrays.stream(array)
            .flatMap(Arrays::stream)
            .iterator();
}

For Integers it would look like this:

public Iterator<Integer> iterator() {
    return Arrays.stream(array)
            .map(Arrays::stream)
            .flatMap(IntStream::boxed)
            .iterator();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.