#java #arrays #multidimensional-array #iterator
#java #массивы #многомерный массив #Итератор
Вопрос:
В настоящее время я пытаюсь настроить пользовательский метод итератора для двумерного массива.
Например. если массив является {{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 ];
}
}
}
Но он не выводит элементы в правильном порядке, а иногда даже возвращает null.
Комментарии:
1. Убедитесь, что массив содержит то, что вы думаете, что он содержит. Либо посмотрите на это в отладчике, либо запишите это в стандартный вывод, используя другую итерацию. Кроме того, взгляните на контракт для Iterator. Ваш следующий метод должен выдавать ошибку
NoSuchElementException
, если он вызывается, когда следующего элемента нет. Кроме того, для надежности и общности рассмотрите возможность проверки,array[currentRow].length
а неarray[0].length
.2. Метод deepToString класса Arrays отформатирует 2D-массив для печати. hasNext также должен проверять значение currentColumn
Ответ №1:
Одно из возможных решений:
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 amp;amp; currentColumn == array[currentRow].length - 1) {
throw new NoSuchElementException();
}
return array[currentRow][currentColumn ];
}
};
}
В качестве альтернативы вы можете использовать Java Streams:
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();
}