Масиви в Java: що це таке і як з ними працювати
Що таке масив?
У програмуванні часто працюють із такою математичною структурою як масив. У мові Java він сприймається як група елементів одного типу.
Масив — це структура фіксованого розміру, її не можна динамічно змінювати, як, наприклад, реалізовано в колекціях Java. У масивів є маса застосувань — від аналізу статистичних даних та аналізу їхньої структури до матричних обчислень та векторних операцій.
Оскільки масив Java є об’єктом, для його створення використовується звичний спосіб: задається змінна (під ім’ям якої ми маємо на увазі сам масив, хоча насправді вона зберігає лише посилання на нього), а потім за допомогою оператора new
описуємо структуру масиву.
Важлива характеристика масиву — його розмірність.
Розмірність — це кількість індексів, необхідних для звернення до елемента масиву. Доступ до будь-якого компоненту масиву здійснюється за допомогою ідентифікатора, який називається індексом елемента.
У цьому слід пам’ятати: нумерація елементів масиву починається з нуля. Найчастіше задіяні одномірні масиви, масиви ж кратністю більше двох використовуються практично дуже рідко.
Важливо: у Java-масиві не можна змішувати типи полів.
Оголошення масиву
Команда для оголошення масиву виглядає так:
типелементів[] ім'я_змінної;
або так:
типелементів ім'я_змінної[];
Обидва записи — рівнозначні.
Процес генерування масиву та запис посилання на нього в змінну виглядає так:
типелементів[] змінна;
змінна=new тип елементів [розмір масиву];
Для обох команд допускається більш коротка форма:
тип елементів[] змінна=new типелементів[розмір_масиву];
Розглянемо загальні форми оголошення одномірного масиву.
Оголошення масиву | Приклад | Коментар |
type variable_name [] |
int anArray [] |
Java-стиль |
type [] variable_name |
int [] anArray |
Стиль, що перекочував у Java з мови програмування С |
При використанні такого оголошення ми маємо знати, що фактичного масиву поки що не існує. Тут ми просто відправляємо повідомлення компілятору, про те, що поле anArray
колись буде пристосовано під масив із цілими числами. Щоб пов’язати anArray
з реальним цілим масивом, потрібно оголосити його за допомогою ключового слова new
:
int[] anArray = new int[10];
У прикладі числове значення у квадратних дужках показує кількість слотів під елементи масиву. У нашому випадку ми виділяємо під масив десять осередків пам’яті.
Наприклад:
int [] anArray; // оголошення масиву anArray = new int [20]; // виділяємо пам'ять для масиву
Або:
int [] intArray = new int [20]; // об'єднуємо оголошення з виділенням пам'яті
Примітка: осередкам у масиві, як виділені за допомогою ключового слова new
, будуть автоматично присвоєні значення: 0 (для числового типу), false (для логічного) та null (для посилань).
Створення масиву
Припустимо, ми хочемо створити масив цілих чисел на 13 елементів. Надамо групі елементів ім’я — highloadToday:
int[] highloadToday = new int[13];
Виведемо на екран довжину масиву:
System.out.println(highloadToday.length);
У консолі відобразиться 13.
Аналогічно створюються набори інших типів. Наприклад, ця команда оголошує масив з десятьма змінними типу double
і надає посилання firstList
:
double[] firstList = new double[10];
Як дізнатися довжину масиву
Ми з вами розібралися, що довжиною масиву є кількість осередків, виділена для зберігання даних, і цю довжину неможливо буде змінити, коли масив вже створено. У Java рахунок елементів по порядку в масиві починається не з одиниці, а з нуля.
Щоб дізнатися довжину нашого масиву, використовуємо його властивість length
. Наприклад:
int[] anArray = new int[10]; // створюємо цілочислений масив на 10 осередків і присвоюємо йому ім'я anArray System.out.println(anArray.length); // виводимо довжину нашого масиву
Ініціалізуємо масив, працюємо з його елементами
Тепер ми знаємо, що таке масив, але як його використовувати поки що незрозуміло. Як завантажувати інформацію, а потім її звідти витягувати? Давайте розбиратися.
У широкому значенні масив — це найважливіша структура даних у програмуванні. Сам комп’ютер — це не що інше, як набір масивів. Байт — це масив із восьми двійкових розрядів, а рядок — це масив символів.
Розробники використовують масиви, тому що вони працюють швидко і дозволяють безпосередньо звертатися до даних окремого елемента за комп’ютерний цикл незалежно від розміру масиву.
Через операційну систему, віртуальну пам’ять та інші фактори для вилучення елемента з масиву може знадобитися трохи більше, ніж один фактичний комп’ютерний цикл. Але час вилучення першого елемента такий самий, як і 100-го елемента і 500-тисячного. Жодна інша створена нами структура даних не може бути швидшою за масив. Усі «просунуті» системи реалізовані з їх використанням.
Тепер давайте з’ясуємо особливості роботи із цією корисною штукою. При оголошенні створюється масив у кожному осередку якого дані за замовчуванням (це ми розібрали). Щоб записати туди необхідні нам дані, потрібно провести обряд ініціалізації, тобто надати кожному осередку певне значення.
Наприклад, створимо масив, що містить у собі чотири сторони світу, і заповнимо його значеннями:
String[] sides = new String[4]; /* оголошеному масиву Java виділив пам'ять для чотирьох рядків (за замовчуванням їх значення буде null, тому що String відноситься до типу посилань)*/ sides[0] = "North"; /* Отримавши доступ до першого осередку (з нульовим індексом), ми вписали туди рядкове значення */ sides[1] = "South"; // теж саме ми робимо з осередком під індексом 1 sides[2] = "West"; // 2 sides[3] = "East"; // 3
Ми використовуємо індекси для доступу до осередків масиву, число в дужках позначає кожну конкретну позицію. Якщо переданий при доступі до осередка індекс — негативний або перевищує довжину масиву, Java видасть виняток ArrayIndexOutOfBoundException
.
Тепер поєднаємо ініціалізацію з оголошенням:
String[] sides = new String[] {"North", "South", "West", "East"};
І приберемо оператор new
, тим самим спростивши запис:
String[] sides = {"North", "South", "West", "East"};
Виводимо масив у консоль
Є кілька способів перебору масивів, один з них циклічний, наприклад, за допомогою циклу for
:
String[] sides = new String[] {"North", "South", "West", "East"}; for (int i = 0; i < 4; i++) { System.out.println(sides[i]); }
Виведе:
North South West East
Багатовимірні Java-масиви
Масиви, у яких лише один індекс називається одновимірним, ми вже розглянули. Але в них можна поміщати не лише примітивні типи даних та посилання на об’єкти, а й інші масиви. У такому разі їх називають багатовимірними.
Давайте на прикладі з’ясуємо, що вони собою являють. Припустимо, нам потрібен масив для зберігання кількості вільних місць у кінотеатрі. Ось візуальне уявлення про те, про що я кажу:
Звичайно в реальному житті кінотеатр був би більшим, але цей нам якраз підійде як приклад.
0 означає, що місце доступне, 1 — що зайняте. Ми також могли б додати ще й 2 для зарезервованих місць тощо. Але поки що обмежимося більш простим прикладом.
Java не надає жодної спеціальної підтримки для багатовимірних масивів, але ми можемо легко оголосити їх як масив масивів. Це буде виглядати так:
int [] [] cinema = новий int [5] [5];
Перше число вказує кількість стовпців, друге кількість рядків. Усі числові масиви Java автоматично ініціалізуються нульовими значеннями після оголошення. Ми щойно створили таблицю, повну нулів.
Тепер давайте заповнимо кінозал одиницями, як на зображенні вище. Для створення рядка з одиниць використовуємо кілька циклів for
. Щоб відкрити доступ до елементів 2D-масиву, ми повинні ввести координати стовпців та рядків:
cinema[2][2] = 1; // центр for (int i = 1; i < 4; i++) { // четвертий рядок cinema[i][3] = 1; } for (int i = 0; i < 5; i++) { // останній рядок cinema[i][4] = 1; }
Потрібно мати на увазі, що якщо ми запитаємо cinema.length
, він міститиме кількість стовпців (довжину зовнішнього масиву, що представляє стовпці). Щоб визначити кількість рядків (довжину внутрішнього масиву) необхідно запросити cinema [0].length
. Зверніть увагу, що для роботи має бути хоча б один стовпець.
Ми вкладатимемо цикли по порядку, щоб зовнішній цикл проходив рядками, а внутрішній — стовпцями поточного рядка. Після виведення рядка в консоль ми повинні розірвати її, адже обидва цикли повинні мати різні змінні, що управляють:
for (int j = 0; j < cinema[0].length; j++) { for (int i = 0; i < cinema.length; i++) { System.out.print(cinema[i][j]); } System.out.println(); }
Результат:
00000 00000 00100 01110 11111
Іноді корисно створити масив з великою кількістю вимірювань. Наприклад, тривимірний. Повернемося до прикладу з кінотеатром. Тепер уявімо, що в ньому кілька поверхів. Схематично це виглядатиме так:
Давайте створимо 3D-масив:
int [] [] [] cinemas = новий int [5] [5] [3];
Доступ до елементів наведеного вище тривимірного масиву ми можемо отримати, як і раніше, через індекс, але тепер нам потрібно ввести три координати:
cinemas[3][2][1] = 1; // кінотеатр на другому поверсі, третій ряд, четверте місце
У такій ситуації, якщо ми запитаємо cinemas[0][0].length
, то отримаємо кількість поверхів.
Робота з масивами
Продемонструємо найпростіші маніпуляції з елементами масиву:
public class Array { public static void main(String[] args) { int[] a = new int[4]; a[0] = 17; //Ініціалізація елементів масиву a[1] = 15; a[2] = 8; a[3] = 8; String[] s = {"October", "November", "December"}; /* Ініціалізацію та оголошення можна застосовувати паралельно*/ String[] s2 = new String[]{"Highload", "Today"}; /*Іноді ініціалізація та оголошення можуть застосовуватись разом з оператором new */ s2[0] = "Highload - "; //Змінюємо перший елемент масиву System.out.println(s2[0] + s2[1]); // Відображення в консолі "Highload - Today" a[2] = 5; // Компоненти масиву - змінні System.out.println(a[2]); } }
Пошук у масиві за елементом
Операція з масивами, які зустрічаються найчастіше, — пошук за елементом. Є багато алгоритмів, що дозволяють її вирішити. Наприклад, можна обрати найбільш легкий, але і найповільніший метод пошуку — лінійний:
public static int linearSearch(int[] array, int elementWanted) { for (int i = 0; i < array.length; i++) { if (array[i] == elementWanted) { return i; } } return -1; }
Якщо наш масив вже впорядкований, можемо застосувати інший спосіб.
Для пошуку:
- ми поділяємо масив на рівні частини;
- дивимося на «центральний елемент» з індексом
middleIndex
; - порівнюємо з розшукуваним елементом;
- якщо є збіг — алгоритм завершуємо.
Коли розшукуваний елемент менше за «центральний елемент» ми забуваємо про праву частину масиву, а інакше — про ліву частину. Потім повторюємо ці дії до виявлення елемента або поки що черговий відрізок не стане порожнім. Якщо елемент не виявлено, повертається значення -1
:
public static int binarySearch(int[] array, int elementWanted) { int firstIndex = 0; int lastIndex = array.length - 1; // умова припинення (елемент не представлений) while (firstIndex <= lastIndex) { int middleIndex = (firstIndex + lastIndex) / 2; // умова припинення (елемент не представлений) if (array[middleIndex] == elementWanted) { return middleIndex; } // коли центральний елемент у масиві менший // переводимо індекс у middle+1, не розглядаючи першу частину else if (array[middleIndex] < elementWanted) { firstIndex = middleIndex + 1; } // якщо центральний елемент більший // переводимо наш індекс у middle-1, не розглядаючи першу частину else if (array[middleIndex] > elementWanted) { lastIndex = middleIndex - 1; } } return -1; }
Сортування масивів
Виконувати впорядкування масиву можна за допомогою методу .sort()
класу Arrays
(не забуваємо на початку програми додавати import java.util.Arrays;
):
int[] highload = { 24, 7, 23, 6765, 95, 33 }; Arrays.sort(highload); System.out.println(Arrays.toString(highload));// [7, 23, 24, 33, 95, 6765]
Більш детально про різні алгоритми сортування масивів можете почитати у статті «Методи сортування та їх реалізація в Python». Незважаючи на те, що ми писали в цій статті про Python, всі алгоритми є актуальними і для Java.
Перетворення масиву на рядок
Іноді може виникнути необхідність перетворення масиву на рядок. Існують різні способи вирішення цього завдання. Наприклад, звернутися до статичного методу join()
класу String
, який поєднує елементи масиву. У цьому прикладі елементи масиву відокремлюються за допомогою вказаним параметром — розділювачем:
String[] words = ["Highload", "Today"]; // Розділювач може бути порожнім рядком String.join("", words); // "HighloadToday" String.join(", ", words); // "Highload, Today"
Java.util.Arrays: готові рішення для обробки масивів
Операції по роботі з java-масивами, що найчастіше використовуються:
- сортування;
- пошук необхідного елемента;
- перетворення масиву на рядок.
Одним із найзручніших способів вирішення такого роду завдань є використання класу Arrays пакету java.util. Розглянемо з прикладу їх реалізацію:
class Main { public static void main(String[] args) { int[] test = {1, 5, 4, 3, 7}; //оголошення та ініціалізація масиву System.out.println(test); //спроба виведення нашого масиву в консоль (результат 16-річне число) System.out.println(Arrays.toString(test)); //виводимо в консоль масив за допомогою методу toString і тішимося вірному результату Arrays.sort(test, 0, 4); //сортування масиву від 0-го до 4-го осередку System.out.println(Arrays.toString(test)); //виводимо результат сортування int keyArray = Arrays.binarySearch(test, 8); // пошук keyArray - тобто числа 8 у відсортованому масиві, метод binarySearch видає індекс шуканого елемента System.out.println(keyArray); //виводимо в консоль цей індекс System.out.println(Arrays.binarySearch(test, 0)); //пробуємо знайти елемент, відсутній у масиві та виводимо результат у консоль } }
Виведе:
[I@1540e19d [1 , 5 , 4 , 3 , 7] [1, 3, 4, 5, 7] 3 -1
Висновок
- Масив — це об’єкт-контейнер, що містить у собі встановлену при створенні кількість значень певного типу, яка не може бути змінена.
- Нумерація елементів масиву починається із нуля.
- Доступ до осередків масиву легко отримати за його індексом.
- Найбільш зручні інструменти для обробки масивів надає клас Java.util.Arrays.
Тепер ви можете самостійно керувати таким важливим математичним інструментом у мові Java. Якщо ви бажаєте закріпити отримані знання, рекомендуємо вам переглянути відео, в якому детально розібрано ряд завдань, пов’язаних з одновимірними та багатовимірними масивами Java:
Favbet Tech – це ІТ-компанія зі 100% украінською ДНК, що створює досконалі сервіси для iGaming і Betting з використанням передових технологіи та надає доступ до них. Favbet Tech розробляє інноваційне програмне забезпечення через складну багатокомпонентну платформу, яка здатна витримувати величезні навантаження та створювати унікальний досвід для гравців.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: