JavaRush /Курси /Java Syntax Zero /Клас Arrays, частина 2

Клас Arrays, частина 2

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

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

Коментарі (28)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Alex Lu Рівень 10
31 травня 2024
в останньому завданні розв'язання не відповідяє умовам. В умові вказано "під час тестування поля класу будуть різними", тобто якщо значення полів буде від'ємним то результат в такому коді буде завжди false
Alex Рівень 2
17 серпня 2024
чому результат завжди буде false? написано ж,

Якщо елемент у масиві не знайдено, індекс буде від'ємним.
тобто якщо шукане значення буде від'ємним - поверне позитивний індекс (від 0 до кінця масиву), тобто 0....+N, а якщо шукане не було знайдено - поверне негативний індекс або -1 (наприклад, якщо шукане 0)
Гаркін Рівень 14
17 лютого 2024
Я вірно зрозумів, що за допомогою що Arrays.copyOf(), що Arrays.copyOfRange() ми запомнюємо лише початок нового масиву? А як скопіювати частину масиву у довільну частину (середину?) іншого масиву? Ще додам. У завданні "Чи є тут хтось?" пам'ятайте, з якого номеру починаються індекси (важливо при перевірці. Я помилився :( . Гарне завдання, яке вказує на недоліки).
Illia_Losiei Рівень 16 Expert
17 жовтня 2023
Дивно. В останньому завданні написав код

        int index = Arrays.binarySearch(array, element);
        boolean result = index < 0 ? false : true;
        System.out.println(result);
Видав помилку другої вимоги: "Під час виклику методу main(String[]) вивести в консоль true, якщо значення змінної element міститься в масиві.", хоча після компіляції в консолі результат "true"
Petro#3337226 Рівень 32
7 листопада 2023
Мені здається вивести треба String, а не boolean
15 листопада 2024
Коментар старий, тому думаю Ви вже давно розібралися з цією задачею, але для майбутніх поколінь можливо знадобиться: Я теж вирішувала через булеву змінну (єдине не тернарником, а через if/else розписувала повністю, але суті не міняє, це одне й те саме ж) Мені здається у Вас задача не пройшла валідацію не через boolean, бо в мене валідатор не сварився на булеву змінну. І виводити String я думаю там точно не потрібно, як в попередньому коментарі написано.. Я думаю помилка через те, що Ви робили бінарний пошук у вже існуючому масиві array, а в умові задачі прописано, що розташування елементів у масиві array не повинно змінюватися. Тобто потрібно створити новий масив, наприклад array2 і скопіювати значення туди з масиву array, відсортувати array2 і вже до нього застосовувати бінарний пошук і частинку коду з тернарним оператором, тоді все має бути ок. Я, на жаль, не можу точно сказати чи пройде валідацію такий варіант коду, бо в мене вже задача вирішена і повторно не дає перевірити, але в IntelliJ все працює.
ZSUnix Рівень 10
17 грудня 2024
A яка різниця? усі методи print... перетворюють отримані дані в строку.
bogdan kravchuk Рівень 11
3 березня 2023
Як ви вже знаєте, розмір контейнера масиву після його створення змінити не можна. А якщо дуже хочеться? Ну, якщо дуже хочеться, то можна 😀😀😀 я просто ржав коли це читав. Головне ж казали що не можна)
Kolapsec Рівень 7
3 грудня 2023
То не можна ж...) зроби собі новий і грайся.
15 листопада 2024
😅😅😅
Роман Рівень 9
30 січня 2023
Останнє завдання жесть. Простеньке, але вірно зробив з 6 спроби. Не уважно читав умову)
Yevhenii Рівень 17
27 грудня 2022
Підкажіть хтось: для чого в завданні hard копіювати масив, якщо і без копіювання програма працює.
Alexoria Рівень 12
3 січня 2023
як ти її запустив без копіювання?
3.14Тарас Рівень 27
18 серпня 2023
Вона працює, але якщо вам знадобиться саме невідредагований масив, то ви його не використаєте, бо він у вас уже відсортований
loms Рівень 11
19 листопада 2022
Чому остання задача hard?
Roma Chernesh Рівень 16
11 грудня 2022
Теж саме питання.
kalkulator¹ Рівень 51
29 жовтня 2022
народ, якщо вирішувати задачі на пустий живіт, нічого не виходить, поїчте і норм (задачу hard з першого разу вирішив)
laura-svg Рівень 12
25 жовтня 2024
А ще добряче поспить)))) (наскільки це можливо в наших умовах)
Andriy Рівень 16
1 жовтня 2022
В першій та другій задачі, крім тернарного оператора або if, ще можна оприділяти середину через ділення з округленням.
Владимир Рівень 32
7 червня 2022
в уроці ( Метод Arrays.binarySearch()) помилка , описано що метод сам сортує масив , а насправді це потрібно зробити самому.
Mutaborrr Рівень 21
14 липня 2022
Це не так. Там сказано : Першим параметром слід передати відсортований масив, в якому виконати пошук, другим параметром — шуканий елемент.