1. Метод Arrays.fill()

Дуже часто у Java-програмістів під час роботи з масивами виникає задача — заповнити масив однаковими значеннями. Можна, звісно, написати цикл і просто в циклі присвоїти кожній комірці масиву певне значення:

int[] x = new int[100];
for (int i = 0; i < x.length; i++)
x[i] = 999;

А можна просто викликати метод Arrays.fill(), який робить абсолютно те саме: заповнює переданий масив переданим значенням. Отакий вигляд має це виклик:

Arrays.fill(ім'я, значення)

І код із прикладу вище можна зробити трохи компактнішим і зрозумілішим:

int[] x = new int[100];
Arrays.fill(x, 999);

А ще за допомогою методу Arrays.fill() можна заповнити певним значенням не весь масив, а його частину:

Arrays.fill(ім'я, перший, останній, значення)

де перший і останній — це номери першої та останньої комірок, які потрібно заповнити.

За старою доброю традицією Java останній елемент не входить в діапазон.

Приклад:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Arrays.fill(x, 3, 7, 999);


String str = Arrays.toString(x);


Заповнюємо комірки x[3], x[4], x[5], x[6] значеннями 999. Нумерація комірок масиву з нуля!

Змінна str містить значення:
"[1, 2, 3, 999, 999, 999, 999, 8, 9, 10]"

Метод Arrays.fill() працює лише з одновимірними масивами. Якщо в нього передати двовимірний масив, цей масив буде оброблено як одновимірний, з усіма наслідками, що звідси випливають.



2. Метод Arrays.copyOf()

Як ви вже знаєте, розмір контейнера масиву після його створення змінити не можна.

А якщо дуже хочеться?

Ну, якщо дуже хочеться, то можна:

  • Створити новий масив потрібної довжини
  • Скопіювати в нього всі елементи з першого масиву

Саме це, до речі, й робить метод Arrays.copyOf(). Викликають його в такий спосіб:

тип[] ім'я2 = Arrays.copyOf(ім'я, довжина);

Цей метод не змінює наявний масив, натомість він створює новий масив і копіює в нього елементи старого.

Якщо елементи не вмістилися (довжина менша за довжину наявного масиву), то зайві значення ігноруються.

Якщо довжина нового масиву більша за довжину старого, комірки буде заповнено нулями.

Приклад:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int[] x2 = Arrays.copyOf(x, 5);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOf(x, 15);
String str3 = Arrays.toString(x3);


Змінна str2 містить значення:
"[1, 2, 3, 4, 5]"

Змінна str3 містить значення:
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0]"

3. Метод Arrays.copyOfRange()

А що робити, якщо ви хочете отримати масив довжиною 5 із масиву довжиною 10, але щоб новий масив містив не перші 5 елементів старого, а останні?

Саме на цей випадок вам стане в пригоді ще один метод класу Arrays — метод Arrays.copyOfRange(). Викликають його в такий спосіб:

тип[] ім'я2 = Arrays.copyOfRange(ім'я, перший, останній);

Цей метод теж створює новий масив, але заповнює його даними з довільного місця початкового масиву. Перший і останній тут — це номери першої та останньої комірок, які потрібно скопіювати.

За старою доброю традицією Java останній елемент не входить в діапазон.

Приклад:

int[] x = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

int[] x2 = Arrays.copyOfRange(x, 5, 10);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOfRange(x, 5, 15);
String str3 = Arrays.toString(x3);


Змінна str2 містить значення:
"[16, 17, 18, 19, 20]"

Змінна str3 містить значення:
"[16, 17, 18, 19, 20, 0, 0, 0, 0, 0]"


4. Метод Arrays.sort()

Ну й найсмачніше — сортування. У програмуванні сортувати масиви доводиться дуже часто. Три найчастіші дії під час роботи з масивами:

  • Сортування масиву
  • Пошук мінімального (або максимального) елемента масиву
  • Визначення індексу елемента в масиві (пошук елемента в масиві)

І саме тому розробники Java включили в клас Arrays метод sort(). Викликають його в такий спосіб:

Arrays.sort(ім'я);

Цей метод сортує переданий масив за зростанням.

Приклад:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x);

String str = Arrays.toString(x);



Змінна str містить значення:
"[-20, -20, -20, -2, 0, 3, 8, 11, 99, 999]"

Чудово, правда? Викликали один метод — і маєте ще й відсортований масив. Краса та й годі.

До речі, сортувати можна не тільки весь масив, а також його частину. Викликають його в такий спосіб:

Arrays.sort(ім'я, перший, останній);

де перший і останній — це номери першої та останньої комірок, до яких треба застосувати сортування.

За старою доброю традицією Java останній елемент не входить в діапазон.

Приклад:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x, 4, 8);
String str = Arrays.toString(x);


Змінна str містить значення:
"[11, -2, 3, 0, -20, -20, 8, 999, 99, -20]"

У Java для сортування масивів використовують найшвидший алгоритм сортування — QuickSort. Швидкість сортування цим методом залежить від розміру масиву й обчислюється за формулою N*Log(N).

Сортування масиву з 1000 елементів налічуватиме близько 3000 порівнянь комірок масиву. Сортування масиву з мільйона елементів налічуватиме близько 6 мільйонів порівнянь.



5. Метод Arrays.binarySearch()

Ну й останній із найцікавіших методів класу Arrays уміє шукати задане значення в масиві. Це не звичайний пошук, а так званий бінарний пошук. Суть його полягає от у чому:

  • Спочатку виконується сортування масиву
  • Потім середній елемент масиву порівнюється із шуканим (з тим, який ми шукаємо).
  • Якщо шуканий елемент більший за середній, пошук продовжується в правій половині масиву.
  • Якщо шуканий елемент менший за середній, пошук продовжується в лівій половині масиву.

Оскільки масив відсортований, можна за одне порівняння відкинути половину масиву. Відтак на наступному кроці відкинути ще половину і т. д.

Завдяки такому підходу бінарний пошук дуже швидкий. У масиві з мільйона (!) елементів він може знайти індекс потрібного елемента всього за 20 порівнянь. Мінус такого підходу в тому, що спершу масив треба відсортувати, а сортування теж потребує часу.

Викликають його в такий спосіб:

int index = Arrays.binarySearch(ім'я, значення);

де ім'я — це ім'я масиву, який потрібно передати вже відсортованим (наприклад, за допомогою функції Arrays.sort()), значення — це той елемент, який ми шукаємо в масиві. Метод повертає результат — індекс шуканого елемента в масиві (номер комірки масиву).

Приклади:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};
Arrays.sort(x);

int index1 = Arrays.binarySearch(x, 0);
int index2 = Arrays.binarySearch(x, -20);
int index3 = Arrays.binarySearch(x, 99);
int index4 = Arrays.binarySearch(x, 5);
x містить:
{-20, -20, -20, -2, 0, 3, 8, 11, 99, 999}

4
1 (також підходили індекси 0 і 2)
8
-7

Якщо шуканих елементів у масиві декілька, метод просто поверне номер одного з них (немає гарантій, що це буде найперший або, навпаки, останній з однакових елементів).

Якщо елемент у масиві не знайдено, індекс буде від'ємним.



6. Посилання на Oracle: документація щодо класу Arrays

Якщо ви неабияк зацікавилися, повну інформацію щодо класу Arrays і всіх його методів можна знайти в офіційній документації на сайті Oracle:

https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Arrays.html

Можете почитати, приміром, про методи Arrays.mismatch() і Arrays.compare(). Певно, знайдете в них для себе щось корисне.

І хай вас не бентежить кількість методів — там кожен метод має 5–10 копій, які відрізняються тільки типом параметрів.