1. Клас Arrays

Як ми вже говорили раніше, масиви — дуже корисна й часто використовувана річ у програмуванні.

Створивши мову Java, її автори невдовзі помітили, що Java-програмісти часто пишуть один і той самий код, коли працюють з масивами. Наприклад: «скопіювати частину масиву в інший масив», «заповнити всі комірки масиву однаковими значеннями», «вивести на екран вміст масиву так, щоб його було зручно читати» тощо.

Тому вони зробили спеціальний клас — Arrays (повне ім'я java.util.Arrays), в який помістили найпопулярніші дії під час роботи з масивами.

У ньому дуже багато методів на всі випадки життя, але спершу ми розглянемо тільки 10 із них — найпростіші та часто використовувані.


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

Перший метод, який ми розглянемо, називається Arrays.toString(). Але спочатку трохи передісторії.

У кожного масиву в Java є метод toString(), який повертає «текстове подання масиву». Отримати текстове подання масиву можна за допомогою такої конструкції:

String str = ім'я.toString();

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

Однак якщо ви спробуєте вивести масив на екран за допомогою методу System.out.println(ім'я), найімовірніше, побачите щось на кшталт:

I@37afeb11

Перша літера I означає, що це масив типу int, а символи після @ — адресу масиву в пам'яті. З одного боку, змінна-масив саме цю інформацію і зберігає, а з іншого — ми очікували на краще, правда ж?

Хотілося б побачити значення, записані в масиві! І от для того, щоб побачити саме значення масиву, і придумали метод Arrays.toString(). Викликають його в такий спосіб:

String str = Arrays.toString(ім'я);

Приклади:

int[] array = {1, 2, 3};
String str = Arrays.toString(array);
Змінна str буде містити значення рядкового типу:
"[1, 2, 3]"
int[] array = {};
String str = Arrays.toString(array);
Змінна str буде містити значення рядкового типу:
"[]"
String[] array = {"Привіт", "Як", "Справи"};
String str = Arrays.toString(array);
Змінна str буде містити значення рядкового типу:
"[Привіт, Як, Справи]"


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

Але якщо ви за допомогою методу Arrays.toString() спробуєте перетворити на рядок (вивести на екран) двовимірний масив, побачите щось знайоме:

[I@37afeb11, I@37afeb21, I@37afeb31]

Уся річ у тім, що в комірках двовимірного масиву зберігаються посилання на одновимірні масиви. А як одновимірні масиви перетворюються на рядки? Саме так, як ви бачите вище.

І що ж робити? Як нам отримати правильне відображення двовимірного масиву?

Для цього клас Arrays має ще один спеціальний метод — deepToString(). Викликають його в такий спосіб:

String str = Arrays.deepToString(ім'я);

У цей метод можна передати двовимірний, одновимірний, тривимірний і взагалі масив будь-якої розмірності, і ми завжди бачитимемо елементи масиву.
Зверніть увагу: метод Arrays.deepToString() не працює з одновимірними масивами примітивів (наприклад, int[]).

Приклади:

Integer[] array = {1, 2, 3};
String str = Arrays.deepToString(array);
Змінна str буде містити значення рядкового типу:
"[1, 2, 3]"
int[][] array = { {1, 1}, {2, 2}, {3, 3} };
String str = Arrays.deepToString(array);
Змінна str буде містити значення рядкового типу:
"[[1, 1], [2, 2], [3, 3]]"
int[][][] array = { {{1, 2, 3}, {1}}, {{}} };
String str = Arrays.deepToString(array);
Змінна str буде містити значення рядкового типу:
"[[[1, 2, 3], [1]], [[]]]"


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

З виведенням масивів на екран ми розібралися, а як бути з порівнянням масивів?

Для порівняння рядків у нас були методи equals та equalsIgnoreCase, а які є методи для подібних операцій з масивами?

Добра новина: для масивів є метод equals, і погана новина — він не порівнює вмісту масивів. Метод equals для масивів робить те саме, що й оператор == — порівнює посилання.

Приклади:

int[] x1 = {1, 2, 3};
int[] x2 = {1, 2, 3};
boolean b = x1 == x2;


false (посилання неоднакові)
int[] x1 = {1, 2, 3};
int[] x2 = {1, 2, 3};
x1.equals(x2);
Метод equals для масивів просто порівнює посилання двох масивів.

false (посилання неоднакові)

І що ж робити? Як порівняти масиви за вмістом?

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

Arrays.equals(ім'я1, ім'я2)

Метод повертає true (істина), якщо масиви мають однакову довжину, а їхні елементи рівні, інакше повертає false (хибність).

Приклади:

int[] x1 = {1, 2, 3};
int[] x2 = {1, 2, 3};
x1.equals(x2);
Метод equals для масивів просто порівнює посилання двох масивів.

false (посилання неоднакові)
int[] x1 = {1, 2, 3};
int[] x2 = {1, 2, 3};
Arrays.equals(x1, x2);


true (вміст масивів однаковий)
int[] x1 = {1, 2, 3};
int[] x2 = {1, 2, 3, 4};
Arrays.equals(x1, x2);


false (вміст масивів різний)

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

І як ви вже, напевно, здогадуєтеся, метод Arrays.equals для двовимірних масивів працюватиме неправильно: він працює з двовимірним масивом як з одновимірним, елементи якого — адреси одновимірних масивів.

Ось чому для правильного порівняння багатовимірних масивів (n=1, 2, 3, …) придумали метод Arrays.deepEquals(). Викликають його в такий спосіб:

Arrays.deepEquals(ім'я1, ім'я2)

Метод повертає true (істина), якщо масиви мають однакову довжину, а їхні елементи рівні, інакше повертає false (хибність). Якщо елементи всередині масиву — теж масиви, для їх порівняння використовують метод Arrays.deepEquals() і т. д.

Приклади:

int[][] x1 = {{1, 2, 3}, {4, 5, 6}};
int[][] x2 = {{1, 2, 3}, {4, 5, 6}};
x1.equals(x2);
Метод equals для масивів просто порівнює посилання двох масивів.

false (посилання неоднакові)
int[][] x1 = {{1, 2, 3}, {4, 5, 6}};
int[][] x2 = {{1, 2, 3}, {4, 5, 6}};
Arrays.equals(x1, x2);
Метод Arrays.equals порівняє x1 і x2 як одновимірні масиви, що зберігають посилання. А посилання в них зберігаються різні.
false (вміст масивів неоднаковий)
int[][] x1 = {{1, 2, 3}, {4, 5, 6}};
int[][] x2 = {{1, 2, 3}, {4, 5, 6}};
Arrays.deepEquals(x1, x2);


true (вміст масивів однаковий)