1. Двовимірні масиви
Ще один цікавий факт про масиви: масиви бувають не лише лінійними, а й двовимірними.
І що це означає, запитаєте ви?
А це означає, що комірки масиву можна представити не тільки у вигляді стовпця (або рядка), а й у вигляді прямокутної таблиці.
int[][] ім'я = new int[ширина][висота];
де ім'я — це ім'я змінної-масиву, ширина — це ширина таблиці (виміряна в комірках), а висота — це висота таблиці. Приклад:
|
Створюємо двовимірний масив: два стовпці та 5 рядків. У комірку (1,1) записуємо 5. |
Отакий вигляд це матиме в пам'яті:
До речі, для двовимірних масивів теж можна використовувати швидку ініціалізацію:
// кількість днів у місяцях року поквартально
int[][] months = { {31, 28, 31}, {30, 31, 30}, {31, 31, 30}, {31, 30, 31} };
Є дуже багато ситуацій, коли вам, як програмісту, може знадобитися двовимірний масив. Реалізація майже будь-якої настільної гри — це ж готовий двовимірний масив: «Шахи», «Шашки», «Хрестики-нулики», «Морський бій»:
Ігрове поле «Шахів» або «Морського бою» просто ідеально лягає на двовимірні масиви, тільки координати клітин треба буде позначати лише числами. Не «пішак 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];
Отакий код допоможе поміняти рядки місцями:
|
Двовимірний масив У matrix[0] у нас зберігається посилання на перший рядок.Міняємо посилання місцями. У результаті масив matrix має такий вигляд:
|
Якщо ви звертаєтеся до комірки двовимірного масиву, але після імені масиву вказуєте тільки один індекс, ви таким чином звернетеся до контейнера контейнерів, у комірках якого зберігаються посилання на звичайні одновимірні масиви.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ