1. Масиви в пам'яті

Малюнки в попередніх прикладах трохи неточні.

Під час створення масивів (як і під час створення рядків) у пам'яті виділяються два блоки: один для зберігання власне масиву (контейнера), а другий — під змінну, що зберігає його адресу. Уточнену ситуацію зображено на малюнку нижче:

Зеленим кольором показано масив на 10 елементів типу int і змінну типу int[], яка зберігає адресу (посилання) масиву типу int у пам'яті.

Для порівняння синім кольором позначено звичайну змінну типу int, яка зберігає значення 199.

Чимось нагадує зберігання рядків у пам'яті, чи не так?

Дійсно, рядки. І так само, як під час операцій з рядками, «змінні типу масив» можна присвоювати одна одній:

Код Пояснення
int[] a = new int[10];
a[2] = 4;
a[7] = 9;
int[] b = a;

a[9] = b[2] + a[7];
Створюємо масив на 10 елементів типу int.
У комірку з індексом 2 записуємо значення 4.
У комірку з індексом 7 записуємо значення 9.
У змінній b зберігаємо адресу, записану в змінній a.
Тепер a і b вказують на один і той самий об'єкт-масив у пам'яті.
У комірку з індексом 9 об'єкта-масиву записуємо суму значень, які зберігаються в комірках 2 (зберігається 4) і 7 (зберігається 9).

При цьому об'єкт-масив залишатиметься на своєму місці, а змінні a і b зберігатимуть однакові адреси (посилання) на один і той самий об'єкт. Погляньте на малюнок:


2. Детальніше про роботу з масивом

Масив можна створити з елементів будь-якого типу. Для цього потрібно лише до назви типу додати квадратні дужки. Загальний вигляд створення масиву такий:

тип[] ім'я = new тип[кількість];

де тип — це тип елементів (комірок) масиву, які ми в ньому зберігатимемо. Ім'я — це ім'я змінної, за допомогою якого ми звертатимемося до масиву, а кількість — це кількість комірок у масиві.

У прикладі вище наведено канонічну форму: створення змінної-масиву та створення об'єкта-масиву. Насправді це дві незалежні конструкції.

Можна створити змінну-масив і об'єкт-масив окремо.

тип[] ім'я;
ім'я = new тип[кількість];

І ще один досить важливий момент:

У ролі індексу масиву та кількості елементів масиву можуть бути змінні та навіть цілі вирази.

Приклади:

Код Пояснення
int n = 100;
int[] a = new int[n];
Створення масиву з n елементів
int n = 100;
int[] a = new int[n * 2 + 3];
Створення масиву з 203 елементів
int n = 100;
int[] a = new int[n];
a[n-1] = 2;
a[n-2] = 3;
a[n/5] = a[n-1] + a[n-2]


// a[99] = 2;
// a[98] = 3;
// a[20] = a[99] + a[98];
Важливо!
До речі, звертаємо вашу увагу, що якщо спробувати звернутися до комірки масиву за індексом, якого в масиві немає (у нашому випадку це всі цілі числа, крім чисел 0..99), програма аварійно завершиться з помилкою ArrayIndexOfBoundException — індекс поза межами масиву.

3. Довжина масиву

Як ви побачили в попередньому прикладі, можна окремо створити змінну типу масив і потім десь у коді присвоїти їй значення (посилання на об'єкт-масив). Можна зробити навіть так:

Код Пояснення
int[] array;
if (a < 10)
   array = new int[10];
else
   array = new int[20];
Створюємо змінну-масив типу int[]
Якщо змінна a менша за 10,
то створити масив із 10 елементів.
Інакше
створити масив із 20 елементів

І як надалі працювати з таким масивом? Як дізнатися, скільки в ньому елементів?

Для цього масив має спеціальну властивість (змінну) — length. І визначити довжину масиву можна за допомогою такого виразу:

array.length;

де array — це ім'я змінної-масиву, а length — це ім'я властивості об'єкта-масиву. Значення у властивості length змінити не можна: саму властивість length можна присвоювати іншим змінним, але їй жодного значення присвоїти не можна (програма просто не скомпілюється).

Отак можна продовжити попередній приклад:

Код Пояснення
int[] array;
if (a < 10)
   array = new int[10];
else
   array = new int[20];
for (int i = 0; i < array.length; i++)
{
   System.out.println(array[i]);
} 
Створюємо змінну-масив типу int[]
Якщо змінна a менша за 10,
то створити масив із 10 елементів.
Інакше
створити масив із 20 елементів
Цикл по всіх елементах масиву: від 0 до довжини array.length – 1

4. Резюмуємо факти про масиви в Java

Резюмуймо відомі факти про масиви:

Факт 1. Масив складається з багатьох комірок.

Факт 2. Доступ до конкретної комірки здійснюється за її номером.

Факт 3. Усі комірки — одного типу.

Факт 4. Початкове значення для всіх комірок — 0 і null (якщо в комірці зберігається адреса), false (для типу boolean). Докладніше про значення за замовчуванням ви дізнаєтеся з цієї лекції.

Факт 5. String[] list — це просто оголошення змінної: сам контейнер (об'єкт-масив) ще не створено. Щоб із ним можна було працювати, потрібно створити масив (контейнер) і записати його в цю змінну, а потім вже ним користуватися. Див. приклади нижче.

Факт 6. Коли ми створюємо об'єкт-масив (контейнер), маємо вказати, якої він довжини, тобто скільки в ньому комірок. Для цього використовуємо таку команду: new TypeName[n];

Факт 7. Довжину масиву можна визначити за допомогою властивості .length.

Факт 8. Після створення масиву не можна змінити ані тип його елементів, ані їх кількість.

Код Пояснення
String s;
String[] list;
s дорівнює null
list дорівнює null
list = new String[10];
int n = list.length;
Змінна list зберігає посилання на об'єкт — масив рядків із 10 елементів.
n дорівнює 10
list = new String[0];

Тепер list містить масив із 0 елементів. Масив є, але зберігати елементи в ньому не можна.

list = null;
System.out.println(list[1]);
Буде згенеровано виняток (помилку програми) — програма аварійно завершиться. list містить порожнє посилання — null
list = new String[10];
System.out.println(list[10]);
Буде згенеровано виняток (помилку програми) — вихід за межі масиву.
Якщо list містить 10 елементів/комірок, то ось їхні допустимі індекси: 0 1 2 3 4 5 6 7 8 9 — загалом 10 значень.