JavaRush/Курсы/Java Syntax Pro/Двумерные массивы

Двумерные массивы

Открыта

1. Двумерные массивы

И еще один интересный факт о массивах. Массивы бывают не только линейными, но и двумерными.

И что это значит, спросите вы?

А это значит, что ячейки массива можно представить не только в виде столбца (или строки), но и в виде прямоугольной таблицы.

int[][] имя = new int[ширина][высота];

Где имя — это имя переменной-массива, ширина — это ширина таблицы (в ячейках), а высота — это высота таблицы. Пример:

int[][] data = new int[2][5];
data[1][1] = 5;
Создаем двумерный массив: два столбца и 5 строк.
В ячейку (1,1) записываем 5.

Вот как это будет выглядеть в памяти:

Двумерные массивы

Кстати, для двумерных массивов можно тоже использовать быструю инициализацию:

// длины месяцев года поквартально
int[][] months = { {31, 28, 31}, {30, 31, 30}, {31, 31, 30}, {31, 30, 31} };

Есть очень много мест, где вам как программисту может понадобиться двумерный массив. Реализация практически любой настольной игры — это же готовый двумерный массив: «Шахматы», «Шашки», «Крестики-Нолики», «Морской бой»:

Двумерные массивы 2

Игровое поле «Шахмат» или «Морского боя» такое, что оно просто идеально ложится на двумерные массивы, только в качестве координат клеток нужно будет использовать только числа. Не «пешка e2 -> e4», а «пешка (4,1) -> (4,3)». Вам как программисту будет даже проще.


2. Расположение элементов в массивах: (x,y) или (y,x)

Тут, кстати, есть интересная дилемма:

Когда мы создаем массив new int[2][5]; у нас таблица «две строки и 5 столбцов» или все-таки «два столбца и 5 строк»? Другими словами, мы сначала задаем «ширину», а потом «высоту» или все-таки сначала «высоту», а потом — «ширину»? И, как говорится, тут не все так однозначно.

Начнем с вопроса: а как эта таблица реально хранится в памяти?

В самой памяти компьютера никаких таблиц нет: все байты памяти пронумерованы как 0, 1, 2, ... Это для нас таблица 2×5, а в памяти это просто 10 ячеек и все. Без разделения, где строки и где столбцы.

Аргумент в пользу гипотезы «ширина»-«высота».

Еще в школе всех учили, что из пары координат сначала указывается «x», а затем «y». И это не просто школьный стандарт — это вообще стандарт в математике. Против царицы наук, как говорится, не попрешь. Так что? Сначала «ширина», а затем «высота»?

Аргумент в пользу гипотезы «высота»- «ширина».

Тут тоже есть интересный аргумент и идет он из... быстрой инициализации двумерных массивов. Ведь если мы захотим инициализировать наш массив, напишем этот код как:

// Важная матрица с данными
int[][] matrix = { {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5} };

Ничего не замечаете? А если так:

// Важная матрица с данными
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {1, 2, 3, 4, 5}
};

Если мы напишем наши данные в коде построчно, то получим таблицу, у которой 2 строки и 5 столбцов.

Итоги

Что тут скажешь? Вам решать, как вам удобнее. Главное, чтобы все программисты, работающие над одним проектом, придерживались одного подхода.

Если вы будете работать над проектом, где много инициализированных двумерных массивов в коде, то скорее всего там все будут отталкиваться от быстрой инициализации данных и будет стандарт «высота»-«ширина».

Если же вам повезет попасть в проект, где много математики и работают с координатами (например, работа с игровыми движками), там скорее всего будут придерживаться подхода «ширина»-«высота»


3. Устройство двумерных массивов

А сейчас вы узнаете, как на самом деле устроены двумерные массивы. Готовы?

Двумерные массивы — это на самом деле массивы массивов!

Другими словами, если в случае с обычным массивом «переменная-массив хранит ссылку на контейнер, который хранит элементы массива». То в случае с двумерными массивами у нас ситуация немного взрывоопаснее: переменная-двумерный-массив хранит ссылку на контейнер, который хранит ссылки на одномерные массивы. Это лучше один раз увидеть, чем сто раз попробовать объяснить:

Устройство двумерных массивов

Слева у нас «переменная-двумерный-массив», которая хранит ссылку на «объект-двумерный массив». В середине у нас «объект двумерный массив», в ячейках которого хранятся ссылки на одномерные массивы — строки двумерного массива. Ну и справа вы видите четыре одномерных массива — строки нашего двумерного массива.

Это то, как на самом деле устроены двумерные массивы. И такой подход дает Java-программисту несколько преимуществ:

Во-первых, т.к. «контейнер контейнеров» хранит ссылки на «массивы-строки», мы можем очень быстро и просто менять строки местами. Чтобы получить доступ к «контейнеру контейнеров», нужно просто указать один индекс вместо двух. Пример:

int[][] data = new int[2][5];
int[] row1 = data[0];
int[] row2 = data[1];

Вот с помощью такого кода можно поменять строки местами:

// Важная матрица с данными
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {5, 4, 3, 2, 1}
};

int[] tmp = matrix[0];
matrix[0] = matrix[1];
matrix[1] = tmp;
Двумерный массив





В matrix[0] у нас хранится ссылка на первую строку.
Меняем ссылки местами.

В итоге массив matrix выглядит так:
{
  {5, 4, 3, 2, 1},
  {1, 2, 3, 4, 5}
};

Если вы обращаетесь к ячейке двумерного массива, но после имени массива указываете только один индекс, вы таким образом обратитесь к контейнеру-контейнеров, в ячейках которого хранятся ссылки на обычные одномерные массивы.



Комментарии (583)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Andrey QA Automation Engineer
8 января, 17:33
До этого проходил https://stepik.org/lesson/296419/step/22?unit=278139 курс по питону. Гораздо круче обьяснение. Хотя работала маленькая команда. А тут какойто бред. Откуда нам знать такое. Показали ноготь а хотят в задачах руку.
Peter QA Performance/Automation
28 января, 02:34
Это принцип обучения сего курса. Это не полностью самодостаточный курс, тут надо изучать дополнительно. На самом сайте javarush тысячи статей по всем темам, доп курсы, видосы, книги, что вам удобней. Плюс, никто не заставляет решать задачи сразу же, всегда можно отложить. Если бы вы были более внимательны и читалли введение а не жмякали кнопки "открыть новую", типа я знаток, уже спец и автоматизатор, то не писали бы этой хероты.
Анна Клушкина
Уровень 13
5 января, 11:55
⛏ В комментариях не менее интересно чем в самой лекции 👀
Dmitry
Уровень 14
13 декабря 2025, 10:30
На удивление быстро решил, минут за 15-20, это очень мотивирует, особенно после прошлой задачи, вот код, который получился: public static void main(String[] args) { MULTIPLICATION_TABLE = new int[10][10]; for(int i=0; i<MULTIPLICATION_TABLE.length; i++){ int a = i+1; for(int j=0; j<MULTIPLICATION_TABLE[i].length; j++){ MULTIPLICATION_TABLE[i][j]=(a*(j+1)); System.out.print(MULTIPLICATION_TABLE[i][j] + " "); } System.out.println(); } } } Вроде лаконично вышло, если вдруг есть какие то правки, то буду рад почитать!:)
d0vbnya
Уровень 2
7 декабря 2025, 12:15
public static void main(String[] args) {
        MULTIPLICATION_TABLE = new int[10][10];
        int num = 1;
        for (int i = 0; i < MULTIPLICATION_TABLE.length; i++)
        {
            for (int j = 0; j < MULTIPLICATION_TABLE[i].length; j++)
            {
                MULTIPLICATION_TABLE[i][j] = (i + 1) * (j + 1);
                System.out.print(MULTIPLICATION_TABLE[i][j] + " ");
            }
            System.out.println();
        }
Магомед
Уровень 7
29 ноября 2025, 17:59
MULTIPLICATION_TABLE = new int [10][10]; MULTIPLICATION_TABLE [0] =new int[] {1,2,3,4,5,6,7,8,9,10}; for ( int a = 0; a < 10;a++ ) { for ( int x = 0; x < 10; x++ ) { MULTIPLICATION_TABLE[a][x]= (MULTIPLICATION_TABLE[0][x] * (a + 1)); System.out.print( MULTIPLICATION_TABLE [a][x] + " "); } System.out.println(); } } } чуть позже до меня дошло , что можно написать проще, не отталкиваясь от первой строки, по формуле MULTIPLICATION_TABLE[a][x] = ( a +1) *( x + 1)
C0N5P1RACY
Уровень 38
27 ноября 2025, 16:33
Что то я не вижу тут комментария "РАБОТАЕМ!!"
29 ноября 2025, 17:36
РАБОТАЕМ !
C0N5P1RACY
Уровень 38
30 ноября 2025, 09:28
XD
SUNSHINE
Уровень 16
24 ноября 2025, 22:03
Подумал над тем, чтобы сделать задачку более универсальной к изменению размерности таблицы) Чтобы массив два раза не изменял одно и то же значение на то же значение - вынес за цикл элемент[0][0]. Т.к. таблица может быть не только квадратной, но и прямоугольной - отдельными циклами заполнил нулевую строку и нулевой столбец(насколько я понял из решения на сайте - это можно было сразу в заполнении массива сделать, но я не додумался) Что скажете, гуру ?) Есть замечания ?) public class Solution { public static int[][] MULTIPLICATION_TABLE; public static void main(String[] args) { MULTIPLICATION_TABLE = new int[10][10]; MULTIPLICATION_TABLE[0][0] = 1; for(int i = 1; i < MULTIPLICATION_TABLE.length; i++) MULTIPLICATION_TABLE[i][0] = i + 1; for(int i = 1; i < MULTIPLICATION_TABLE[0].length; i++) MULTIPLICATION_TABLE[0][i] = i + 1; for(int i = 1; i < MULTIPLICATION_TABLE.length; i++) for(int j = 1; j < MULTIPLICATION_TABLE[i].length; j++) MULTIPLICATION_TABLE[i][j]= MULTIPLICATION_TABLE[i][0] * MULTIPLICATION_TABLE[0][j]; for(int i = 0; i < MULTIPLICATION_TABLE.length; i++) { for(int j = 0; j < MULTIPLICATION_TABLE[i].length; j++) System.out.print(MULTIPLICATION_TABLE[i][j] + " "); System.out.println(); } } }
Alex
Уровень 10
18 ноября 2025, 08:45
Предлагаю свой код с использованием параметра для форматирования printf + "%4d" int[][] MULTIPLICATION_TABLE = new int[10][10]; for (int i = 1; i <= 10; i++) { for (int j = 1; j <=10; j++) { MULTIPLICATION_TABLE[i][j] = i * j; System.out.printf("%4d", MULTIPLICATION_TABLE[i][j]); } System.out.println(); }
techn0di
Уровень 25
3 ноября 2025, 14:38
Все гордятся коротким кодом, который у всех с первого раза зашел вот мой: MULTIPLICATION_TABLE = new int[10][10]; for (int i = 0; i < MULTIPLICATION_TABLE.length; i++) { for (int j = 0; j < MULTIPLICATION_TABLE[i].length; j++) { if (i == 0 && j == 0) { MULTIPLICATION_TABLE[i][j] = 1; } if (i == 0 && j != 0) { MULTIPLICATION_TABLE[i][j] = MULTIPLICATION_TABLE[i][j-1] + 1; } if (i != 0 && j == 0) { MULTIPLICATION_TABLE[i][j] = MULTIPLICATION_TABLE[i-1][j] + 1; } if (i != 0 && j != 0) { MULTIPLICATION_TABLE[i][j] = (i + 1) * (j + 1); } if (j == 9) { System.out.println(MULTIPLICATION_TABLE[i][j]); } else { System.out.print(MULTIPLICATION_TABLE[i][j] + " "); } } } Ребята, которые пришли из гуманитарных направлений, не сдавайтесь! все получится :)
Denis Skab
Уровень 8
2 октября 2025, 10:40
а почему не зделать в место пробела между числами "\t" так таблица красиво выглядит, самое интересное что в Java25 вы именно это и запрашиваете а тут это ошибка