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


Коментарі (29)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
VladykaUA Рівень 21
23 жовтня 2025
останнє завдання із зірочкою. задача стоїть повернути true або false. Це можна зробити без сортування масиву, але ця задача хоче, щоб у пошуку був застований відсортований масив, прицьому орігінальний масив змінювати не можна)))
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
hidden #3500645 Рівень 30
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
То не можна ж...) зроби собі новий і грайся.
hidden #3500645 Рівень 30
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 Рівень 14
25 жовтня 2024
А ще добряче поспить)))) (наскільки це можливо в наших умовах)
Andriy Рівень 16
1 жовтня 2022
В першій та другій задачі, крім тернарного оператора або if, ще можна оприділяти середину через ділення з округленням.