JavaRush /Java блог /Random UA /Дещо про масиви в Java

Дещо про масиви в Java

Стаття з групи Random UA
Вітання! Раніше, під час навчання, ми працювали з одиничними об'єктами (або примітивними типами). Але якщо нам потрібно працювати не з одним об'єктом, а з цілою групою? Наприклад, ми хочемо створити список днів народження всіх працівників нашої компанії. Він має містити, скажімо, 30 рядків у форматі: "Андрій Петроов, 25 січня". Тут нам допоможе спеціальна структура даних – масив. Якщо порівняти масив з предметами з реального життя, його пристрій дуже схоже на банківське сховище з осередками: Дещо про масиви в Java - 1Масив теж складається з осередків. У кожен осередок ти можеш щось покласти. При цьому для доступу до вмісту потрібно знати номер комірки. Створюється масив ось так:
public class Main {

   public static void main(String[] args) {

       String [] birthdays = new String[10]; //масив рядків Java

   }
}
Тут ми створабо масив на 10 осередків. Ти одразу можеш звернути увагу на деякі особливості масиву:
  1. Він зберігає дані строго певного типу. Якщо ми спочатку створабо масив рядків String, ми не зможемо зберігати в ньому щось інше. Тип даних вказується під час створення масиву. У цьому його відмінність від банківського осередку, у якому клієнт може зберігати що захоче.
  2. Масив може зберігати дані примітивних типів (наприклад, int), рядки ( String) чи об'єкти одного класу. Точніше навіть самі об'єкти, а посилання ці об'єкти.
  3. Розмір масиву обов'язково вказується під час створення. Вказати його пізніше або змінити розмір після створення не вдасться.
На те, що створюється саме масив, Java вказує квадратними дужками []в обох виразах. Їх можна вказати до назви змінної-посилання або після — працюватиме і так, і так:
//Java-масиви рядків, два варіанти синтаксису
String [] birthdays = new String[10];
String birthdays [] = new String[10];
Якщо ти хочеш щось записати в масив, тобі потрібно вказати номер осередку, в якому буде записано значення. Номери осередків масиву починається з 0. Починати відлік з нуля — найпоширеніша практика в програмуванні. Чим швидше ти до цього звикнеш, тим краще:) Дещо про масиви в Java - 2Тобто якщо ти хочеш покласти якесь значення в перший осередок масиву , це робиться так:
public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Олена Єлісєєва, 12 березня";
   }
}
Тепер у першому осередку нашого масиву, який містить дні народження колег, зберігається рядок із днем ​​народження Олени. За аналогією можна додати інші значення:
public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Олена Єлісєєва, 12 березня";
       birthdays[1] = "Коля Романов, 18 травня";
       birthdays[7] = "Олеся Остапенко, 3 січня";
   }
}
Зверни увагу: день народження Олесі ми додали до восьмого осередку (не забув ще, чому осередок №7 — восьмий?). Хоча всі інші осередки у нас не заповнені. Не обов'язково записувати значення масиву по порядку — такого обмеження немає. З іншого боку, якщо записуватимеш по порядку, набагато простіше стежитиме за кількістю вільних і зайнятих осередків, і в масиві не залишатиметься "дір". Якщо ти хочеш отримати вміст осередку масиву, як і у випадку з банківським, тобі потрібно знати її номер. Робиться це так:
public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Олена Єлісєєва, 12 березня";
       birthdays[1] = "Коля Романов, 18 травня";
       birthdays[7] = "Олеся Остапенко, 3 січня";

       String olesyaBirthday = birthdays[7];
       System.out.println(olesyaBirthday);
   }
}
Виведення в консоль:

Олеся Остапенко, 3 января
Ми створабо змінну Stringі сказали компілятору: "Знайди комірку з індексом 7 в масиві birthdaysі присвоє значення, яке там зберігається, в змінну String olesyaBirthday". Саме це він і зробив.

Довжина масиву Java

Працюючи з масивом ти можеш легко дізнатися його довжину з допомогою спеціального властивості — length.
public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Олена Єлісєєва, 12 березня";
       birthdays[1] = "Коля Романов, 18 травня";
       birthdays[7] = "Олеся Остапенко, 3 січня";

       int birthdaysLength = birthdays.length;
       System.out.println(birthdaysLength);
   }
}
Виведення в консоль:

10
Зауваж:як lengthзберігається розмір масиву, а чи не кількість заповнених осередків. Наш масив зберігає лише 3 значення, але при створенні ми вказали йому розмір = 10. Саме це значення повертає поле length. Навіщо це може стати в нагоді? Ну, наприклад, якщо ти захочеш вивести в консоль список усіх днів народження (щоб перевірити, що нікого не забули), це можна зробити в одному простому циклі:
public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Олена Єлісєєва, 12 березня";
       birthdays[1] = "Коля Романов, 18 травня";
       birthdays[2] = "Віка Ігнатова, 12 липня";
       birthdays[3] = "Деніс Козлов, 7 вересня";
       birthdays[4] = "Максим Масленников, 9 листопада";
       birthdays[5] = "Роман Баранов, 14 серпня";
       birthdays[6] = "Валерія П'яткіна, 1 квітня";
       birthdays[7] = "Олеся Остапенко, 3 січня";
       birthdays[8] = "Костя Гурко, 19 жовтня";
       birthdays[9] = "Сергій Наумов, 3 травня";

       for (int i = 0; i < birthdays.length; i++) {
           System.out.println(birthdays[i]);
       }
   }
}
У циклі ми створюємо змінну i, яка спочатку дорівнює нулю. При кожному проході ми беремо комірку з індексом i з нашого масиву та виводимо її значення на консоль. Цикл зробить 10 ітерацій, і значення i збільшуватимуться від 0 до 9 — саме за індексами осередків нашого масиву! Таким чином ми виведемо в консоль всі значення від birthdays[0]до birthdays[9] Насправді є способи створити масив по-іншому. Наприклад, масив чисел intможна створити так:
public class Main {

   public static void main(String[] args) {
       int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
   }
}
Цей спосіб називається "швидкою ініціалізацією". Він досить зручний тим, що ми одразу створюємо масив і заповнюємо його значеннями. Не потрібно явно вказувати розмір масиву — поле lengthпри швидкій ініціалізації заповниться автоматично.
public class Main {

   public static void main(String[] args) {
       int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
       System.out.println(numbers.length);
   }
}
Виведення в консоль:

9

Масив об'єктів Java

Ти вже чув, що масиви об'єктів та масиви примітивів по-різному зберігаються у пам'яті. Візьмемо, наприклад, масив із трьох об'єктів Cat:
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Томас");
       cats[1] = new Cat("Бегемот");
       cats[2] = new Cat("Філіп Маркович");
   }
}
Тут треба розуміти кілька речей:
  1. Що стосується примітивами масиви Java зберігають безліч конкретних значень (наприклад, чисел int). Що стосується об'єктами масив зберігає безліч посилань. Масив catsскладається з трьох осередків, у кожному з яких є посилання на об'єкт Cat. Кожне з посилань вказує на адресау пам'яті, де цей об'єкт зберігається.
  2. Елементи масиву у пам'яті розміщуються в єдиному блоці. Це зроблено для більш ефективного та швидкого доступу до них. Таким чином, посилання catsвказує на блок пам'яті, де зберігаються всі об'єкти - елементи масиву. А cats[0]на конкретну адресау всередині цього блоку.
Дещо про масиви в Java - 3Важливо розуміти, що масив не тільки може зберігати об'єкти — він і сам є об'єктом.

Масив масивів або двовимірний масив

Виходячи з цього перед нами постає питання — а чи можемо ми створити, наприклад, не масив рядків чи чисел, а масив масивів? І відповідь буде – так, можемо! Масив може зберігати в собі будь-які об'єкти, включаючи інші масиви. Такий масив називатиметься двовимірним. Якщо зобразити його на зображенні, він буде дуже схожий на звичайну таблицю. Наприклад, ми хочемо створити масив, який зберігатиме 3 масиви чисел intпо 10 осередків у кожному. Виглядатиме це так: Дещо про масиви в Java - 4Кожен рядок зображує масив чисел int. Перший масив містить числа від 1 до 10, другий - від -1 до -10, третій - набір випадкових чисел. Кожен із цих масивів зберігається в осередку нашого двовимірного масиву. Ініціалізація двовимірного масиву в коді виглядає так:
public static void main(String[] args) {
   Cat[][] cats = new Cat[3][5];
}
Наш двомірний масив cats зберігає 3 масиви по 5 осередків у кожному. Якщо ми хочемо покласти наш об'єкт у третій осередок другого масиву, це робиться так:
public static void main(String[] args) {
   Cat[][] cats = new Cat[3][5];
   cats[1][2] = new Cat("Пушок");
}
[1]вказує на другий масив, а [2]- на третій осередок цього масиву. Оскільки двовимірний масив складається з декількох масивів, щоб його обійти і вивести в консоль всі значення (або заповнити всі комірки), нам знадобиться вже подвійний, вкладений цикл:
for (int i = 0; i < cats.length; i++) {
   for (int j = 0; j < cats[i].length; j++) {
       System.out.println(cats[i][j]);
   }
}
У зовнішньому циклі (змінна i) ми по черзі обходимо всі масиви, з яких складається наш двомірний масив. У внутрішньому циклі (змінна j) ми перебираємо всі осередки кожного масиву. У результаті першим буде виведено на консоль об'єкт cats[0][0](перший масив, перший осередок), другим - cats[0][1](перший масив, другий осередок). Коли перший масив буде вичерпаний - виводитимуться cats[1][0], і так далі. До речі, для двовимірних масивів також доступна швидка ініціалізація: cats[1][1]cats[1][2]
int[][] numbers = {{1,2,3}, {4,5,6}, {7,8,9}};
У звичайному вигляді ми записали б двовимірний масив numbersяк int[3][3], а такий спосіб дає нам можливість відразу вказати значення. Навіщо двовимірний масив може знадобитися? Ну, наприклад, за його допомогою ти легко можеш відтворити знамениту гру "Морський бій": Дещо про масиви в Java - 5Структура ігрового поля в "Морському бою" така, що її можна легко описати: двомірний масив із 10 масивів, по 10 осередків у кожному. Ти створюєш два такі масиви — для себе та свого супротивника:
int [][] seaBattle = new int[10][10];
int [][] seaBattle2 = new int[10][10];
Ви заповнюєте якимись значеннями (наприклад, цифрами або знаками *) ті осередки, в яких розташовуються твої кораблі, а потім ви з супротивником по черзі називаєте номери осередків:
  • seaBattle[6][5]!
  • Мимо! seaBattle2[6][6]!
  • Поранений!
  • seaBattle2[6][7]!
  • Поранений!
  • seaBattle2[6][8]!,
  • Вбито!

Додаткові матеріали про масиви

Хочете знати більше про масиви? Зверніть увагу на статті нижче. Там багато цікавого та корисного з цієї теми.
  1. Масиви в Java — докладна стаття про масиви, їх створення, ініціалізацію та використання. Із прикладами.
  2. Клас Arrays та його використання - у статті описані деякі методи класуArray
  3. Масиви – перша лекція JavaRush, присвячена масивам.
  4. Багатомірні масиви - докладна стаття про багатовимірні масиви з прикладами.
  5. Повертайте масив нульової довжини, а не null – автор "Ефективного програмування" Джошуа Блох розповідає про те, як краще повертати порожні масиви.
У цьому наше перше знайомство з масивами закінчено, але це лише початок взаємодії із нею. У наступних лекціях ми побачимо цікаві способи їх застосування, а також дізнаємось які в Java є вбудовані функції для зручнішої роботи з цією структурою даних:)
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ