JavaRush /Курси /Java Syntax Zero /Нюанси роботи з масивами

Нюанси роботи з масивами

Java Syntax Zero
Рівень 6 , Лекція 2
Відкрита

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

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), програма аварійно завершиться з помилкою ArrayIndexOutOfBoundsException — індекс за межами масиву.

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 штук.

Коментарі (55)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Anonymous #3619820 Рівень 6
19 вересня 2025
Чому з System.out.println("") усе виводится правильно а перевірка каже що там щось не так.

package ua.javarush.task.pro.task05.task0504;

/* 
Об'єднуємо масиви
*/

public class Solution {
    public static int[] firstArray = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    public static int[] secondArray = new int[]{10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
    public static int[] resultArray;

    public static void main(String[] args) {
        //напишіть тут ваш код
        resultArray = new int[20];
        for (int i = 0; i < resultArray.length; i++) {
            if(i < 10) {
                resultArray[i] = firstArray[i];
            }
            else {
                resultArray[i] = secondArray[i - 10];
            }

            System.out.println(resultArray[i]);
        }
    }
}

Konstantin Рівень 6
6 травня 2025
public class Solution { public static int[] firstArray = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; public static int[] secondArray = new int[]{10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; public static int[] resultArray; public static void main(String[] args) { resultArray = new int [firstArray.length + secondArray.length]; System.arraycopy(firstArray, 0, resultArray, 0, firstArray.length); System.arraycopy(secondArray, 0, resultArray, firstArray.length, secondArray.length); for (int i = 0; i < resultArray.length; i++) { System.out.print(resultArray[i] + ", "); } } }
2 березня 2025
був чуть обурений після задачі про копіювання масивів(( валідатор зараховує завдання тільки якщо написати 2 окремі цикли.. я зробив одним і майже годину не міг зрозуміти, в чому проблема. виправте це, за можливості, дякую!
hidden #3500645 Рівень 30
28 жовтня 2024
Підкажіть, будь ласка, останній приклад в лекції: Що це за одиничка і що вона означає? Цикл по всіх елементах масиву: від 0 до довжини array.length – 1

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]);
}
IronMan57 Рівень 28
19 листопада 2024
Оскільки індекси елементів масиву завжди починаються з нуля, то індекс останнього елемента в масиві буде завжди на одиницю менший, чим кількість елементів у ньому. Наприклад ініціалізуємо масив з трьох елементів: int length = 3; int[] array = new int[length]; Тоді у першого елемента індекс = 0, у другого = 1, у третього (і останнього у цьому масиві) = 2. Властивість массиву array.length у цьому випадку дорівнюватиме 3. Тому у циклі звернення до елементів масиву буде: array[0], array[1], array[2]. Також тому в умові продовження циклу for задано, що індекс повинен бути менший кількості елементів (довжини): i < array.length.
hidden #3500645 Рівень 30
20 листопада 2024
дякую за відповідь, вже розібралася) це зрозуміло, що у масиві індекс буде в останнього елемента на 1 менший, ніж фактична довжина, тому що нумерація з нуля і якщо взяти елемент з індексом, що дорівнює фактичній кількості елементів масиву буде помилка ArrayIndexOutOfBoundsException, бо його не існуватиме, останній елемент< array.length на одиничку там просто в лекції замість мінусу тире стоїть і тому не могла зрозуміти, до чого там одиничка створила запит в розділі підтримки і підказали, що просто невірно прочитала "Цикл по всіх елементах масиву: від 0 до довжини array.length – "не тире 1, а мінус 1" забула просто, що тут теж коментар залишала)
Alex Рівень 2
7 серпня 2024

resultArray = new int[firstArray.length + secondArray.length];

        for (int i = 0; i < firstArray.length; i++) {
            resultArray[i] = firstArray[i];
        }

        for (int i = 0, j = resultArray.length / 2; i < secondArray.length; i++, j++) {
            resultArray[j] = secondArray[i];
        }
працює правильно, але не проходить останній тест(
Dmytro Рівень 26
5 червня 2024
почеум не принимает такое решение?

        resultArray = new int[firstArray.length + secondArray.length];
        for (int i = 0; i < firstArray.length; i++) {
            resultArray[i] = firstArray[i];
        }
        for (int i = 10; i < resultArray.length; i++) {
            resultArray[i] = secondArray[i - 10];
        }
Dmytro Рівень 26
5 червня 2024
понял почему. надо использовать не 10, а длину первого массива, тогда принимает
Ivan Kravets Рівень 22
10 грудня 2023
ініціалізацію ressArray потрібно робити в методі main
Volodymyr Victorovich Рівень 12
26 серпня 2025
дякую!
17 вересня 2023
Довго мучився, спочатку написав код, що був поза межами лекцій, та допомогою оцієї елегантної конструкції:

resultArray = IntStream.concat(IntStream.of(firstArray), IntStream.of(secondArray)).
Але валідацію не пройшов останнім пунктом. Пішов гортати "допомогу спільноти". Зрозумів, що в людей +/- такі самі питання, вирішив спробувати ще якісь варіанти. Дякуючи коментарю шановного Roma Chernesh, зрозумів, куди саме рити. Але, людоньки, будьте дуже уважні, бо можна ненароком зайвий "if" вставити, а потім дивитись квадратними очима на червону консольку. Взагалом так. Задача, по суті, вирішується з допомогою цикла "if-else" і, ні в якому разі не указуйте жодної цифри, окрім "0", яким задається початковий параметр для змінної
Kolapsec Рівень 7
27 листопада 2023
2 цикла for, 8 рядків коду
Гаркін Рівень 14
14 лютого 2024
написати треба 1 цикл for. Другий - це вже вивід на друк. Як? Ось моє рішення:
Ivan Maksymovych Рівень 1 Expert
9 серпня 2023
Нашел такой интересный класс как IntStream, он как раз то что тут нужно)) Самое простое и легкое решение получается)

resultArray = IntStream.concat(IntStream.of(firstArray), IntStream.of(secondArray)).toArray();
По сути мы берем в поток наши значения с первого массива, и со второго благодаря IntStream.of(); делаем конкатенацию благодаря IntSteam.concat(), и все это засовываем в массим благодаря .toArray(), как по мне то очень удобно))
Олексій Моцьор Рівень 27 Expert
15 липня 2023
Копіювання зробив через System.arraycopy() результат вийшов правильний але валідатор не пропускає. Хоче щоб копіювали через цикли....Цікаво хто буде городити таку програму, якщо є простий метод копіювання масивів?
23 липня 2023
Звучить логічно, але ж суть уроку опанувати цикли і роботу з масивами, щоб застовувати цей досвід в майбутньому
Vitalii Рівень 11
29 липня 2023
в умовах нічого не написано про цикли. тому і логіки ніякої тут нема