Как реализовать пользовательский итератор для многомерного массива в Java? - PullRequest
1 голос
/ 30 марта 2019

В настоящее время я пытаюсь настроить пользовательский метод Iterator для двумерного массива.

например. если массив равен {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, метод next() должен возвращаться последовательно при каждом вызове 1, 2, 3, 4, 5, 6, 7, 8, 9.

Моя идея была примерно такой:

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++];
        }
    }
}

Но он не выводит элементы в правильном порядке, а иногда даже возвращает ноль.

1 Ответ

1 голос
/ 30 марта 2019

Одно из возможных решений:

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++];
        }
    };
}

В качестве альтернативы вы можете использовать потоки Java:

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

Для целых чисел это будет выглядеть так:

public Iterator<Integer> iterator() {
    return Arrays.stream(array)
            .map(Arrays::stream)
            .flatMap(IntStream::boxed)
            .iterator();
}
...