Многомерные массивы
Данные часто имеют форму таблицы: места в зале, клетки игрового поля, оценки учеников по предметам. Для них в Java используют двумерный массив — массив, каждый элемент которого сам является массивом-строкой.
Создание таблицы
Тип двумерного массива пишут с двумя парами скобок: int[][]. Значения задают вложенными фигурными скобками — каждая внутренняя пара описывает одну строку:
void main() {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
IO.println(matrix[0][2]);
IO.println(matrix[1][0]);
}Результат:
3
4Первый индекс выбирает строку, второй — столбец в ней. Оба начинаются с нуля.
Размеры
matrix.length — количество строк, а matrix[i].length — длина конкретной строки. Пустую таблицу создают через new с двумя размерами; элементы получают значения по умолчанию:
void main() {
int[][] seats = new int[3][4];
seats[1][2] = 1;
IO.println("Рядов: " + seats.length);
IO.println("Мест в ряду: " + seats[0].length);
IO.println(seats[1][2] + " " + seats[1][3]);
}Результат:
Рядов: 3
Мест в ряду: 4
1 0Измерений может быть и больше двух, например int[][][], но на практике такие массивы встречаются редко.
Обход вложенными циклами
Чтобы пройти все элементы, используют два цикла: внешний перебирает строки, внутренний — элементы строки:
void main() {
int[][] board = {
{1, 0, 1},
{0, 1, 0},
{1, 0, 1}
};
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
IO.print(board[row][col] == 1 ? "X " : ". ");
}
IO.println();
}
}Результат:
X . X
. X .
X . Xfor-each для таблицы
С for-each внешний цикл получает строки целиком, то есть массивы int[], а внутренний — числа:
void main() {
int[][] sales = {
{120, 80},
{95, 110},
{60, 70}
};
int total = 0;
for (int[] week : sales) {
for (int amount : week) {
total += amount;
}
}
IO.println("Всего продаж: $" + total);
}Результат:
Всего продаж: $535Рваные массивы
Строки двумерного массива не обязаны быть одной длины. Такой массив называют рваным (jagged). Для его вывода удобен Arrays.deepToString():
void main() {
int[][] triangle = new int[3][];
triangle[0] = new int[]{1};
triangle[1] = new int[]{1, 1};
triangle[2] = new int[]{1, 2, 1};
IO.println(Arrays.deepToString(triangle));
}Результат:
[[1], [1, 1], [1, 2, 1]]new int[3][] создаёт только внешний массив из трёх пустых мест, а строки разной длины добавляются потом. Обычный Arrays.toString() для двумерного массива вывел бы служебные описания строк вместо чисел.
Частая ошибка
Легко перепутать количество строк и столбцов. Если таблица не квадратная, matrix.length во внутреннем цикле выводит индекс за пределы строки:
void main() {
int[][] matrix = {
{1, 2},
{3, 4},
{5, 6}
};
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix.length; col++) {
IO.print(matrix[row][col] + " ");
}
}
}Результат:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2Во внутреннем цикле нужна длина текущей строки: col < matrix[row].length.