Как реализовать интерфейс Iterator для многомерного массива?
Ввод:
int[][] arr = {{1, 2, 3}, {4, 5}};
Вывод:
1
2
3
4
5
Предполагаю, что сделать 2 итератора по столбцу и строке.
public class MatrixIterator implements Iterator {
private int[][] values;
private int rowIndex = 0;
private int colIndex = 0;
private Iterator<Integer> rowIterator;
private Iterator<Integer> colIterator;
public MatrixIterator(int[][] values) {
this.values = values;
rowIterator = new Iterator<Integer>() {
@Override
public boolean hasNext() {
return values.length > rowIndex;
}
@Override
public Integer next() {
return values[rowIndex++][colIndex];
}
};
colIterator = new Iterator<Integer>() {
@Override
public boolean hasNext() {
return values[rowIndex].length > colIndex;
}
@Override
public Integer next() {
return values[rowIndex][colIndex++];
}
};
}
@Override
public boolean hasNext() {
if (rowIterator.hasNext() && colIterator.hasNext()) {
return true;
} else {
return false;
}
}
@Override
public Object next() {
if (rowIterator.hasNext()) {
if(colIterator.hasNext()){
return values[rowIndex][colIndex++];
}
else {
colIndex =0;
return values[rowIndex++][colIndex];
}
}
else return null;
}
}
Тогда как правильно реализовать методы основного класса?
Для последовательного обхода элементов можно сделать так:
public class MatrixIterator<T> implements Iterator<T>{
private int size; //всего элементов в матрице
private int position = 0; //номер текущего элемента для "выдачи"
private int row = 0; //строка текущего элемента
private int col = 0; //столбец текущего элемента
private T[][] matrix;
public MatrixIterator(T[][] matrix) {
this.matrix = matrix;
this.size = countElements(matrix);
}
private int countElements(T[][] matrix) { //считаем количество элементов в матрице
int count = 0;
for (T[] row : matrix) {
count += row.length;
}
return count;
}
@Override
public boolean hasNext() {
return position < size;
}
@Override
public T next() {
if (position >= size) { //если перебрали все элементы, то бросить исключение
throw new NoSuchElementException();
}
T element = matrix[row][col]; //запоминаем текущий элемент
//переходим к следующему элементу
position++;
col++;
while (row < matrix.length && col >= matrix[row].length) { //для того, чтоб пропустить возможные "пустые" строки
col = 0;
row++;
}
return element;
}
}
В данном случае итератор параметризирован, так что не имеет значения с матрицей какого типа работать. В row
и col
сохраняется позиция текущего элемента, который необходимо вернуть. Цикл while
для того, чтоб пропустить возможные пустые строки (например, {{1, 2, 3}, {}, {4, 5}, {6}}
). Использовать итератор можно следующим образом
Integer[][] matrix = {{1, 2, 3}, {}, {4, 5}, {6}};
Iterator<Integer> iterator = new MatrixIterator<>(matrix);
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
Вывод:
1
2
3
4
5
6
Можно попробовать внутри hasNext()
итерироваться по массиву с помощью forEach
и выдавать нужный объект.
private class ElementsIterator implements Iterator<T> {
T[][] value;
private int cursor = 0;
@Override
public boolean hasNext() {
return cursor != size;
}
@Override
public T next() {
//Равен нулю каждый раз при входе в метод.
int nextCursor = 0;
for (T x[]: value) {
for (T y : x) {
//сброшенный nextCursor поднимается
//до уровня текущей позиции cursor
//и отдает нужный элемент.
if (nextCursor++ == cursor) {
cursor++;
return y;
}
}
}
//Если перед вызовом next()
//проверять есть ли элементы,
//то сюда у нас программа не дойдет.
throw new NoSuchElementException();
}
}
Другой вариант:
public class IteratorFor2DArray implements Iterator {
private int[][] data;
private int i, j;
public IteratorFor2DArray(int[][] data) {
this.data = data;
}
@Override
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
int element = data[i][j];
j++;
while (i < data.length && j >= data[i].length) {
j = 0;
i++;
}
return element;
}
@Override
public boolean hasNext() {
return (i < data.length && j < data[i].length);
}
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Когда выполнение кода метода doGet сервлета доходит до момента обращения к базе через hibernate в логе появляется нижеуказанная ошибка и останавливается...
Есть файл jsp поставляется в библиотеке, менять не могу, но мне нужно передать параметр в этот jspGри передаче тегом param переменная text появляется...
Подскажите пожалуйста, почему результат сложения получается "10E-7", а не "0
В своем проекте использую библиотеку Jackson для сериализации объектов в JSONПри использовании @JsonFormat устанавливается дата на один день раньше