JavaRush /Java блог /Random UA /Клас Arrays та його використання

Клас Arrays та його використання

Стаття з групи Random UA
І знову привіт! :) На минулому занятті ми познайомабося з такою структурою даних як масив (Java array), навчабося створювати масиви, наповнювати даними, а також дізналися, як вони зберігаються у пам'яті. Сьогодні ми розглянемо деякі завдання та приклади роботи з масивами, які часто зустрічатимуться тобі в реальній роботі. Наприклад, уяви собі таку ситуацію: у нас є масив із 10 чисел, записаних у випадковому порядку.
//array Java, example
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
Наше завдання полягає в тому, щоб відсортувати цей масив за зростанням: від менших чисел до більших. У результаті він має виглядати так:
[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
Як це зробити? Завдання нетривіальне, такого ми ще не робабо :/ Є якісь ідеї? Спробуй припустити. Ось що, наприклад, ми можемо зробити:
  • Пройтися всіма елементами масиву. Порівнювати кожен елемент із наступним ( [0]з [1], [1]з [2], [2]з [3]і т.д.). Якщо поточний елемент масиву більший за наступний, змінюємо їх місцями і переходимо до наступного елемента. Якщо ні – залишаємо як є і йдемо далі.

  • Таким чином, після першого проходження по елементах масиву найбільше значення (167) гарантовано буде в останній комірці.

  • Тепер знову пройдемо по всіх елементах масиву починаючи з елемента з індексом [0], але до передостаннього елемента (найбільше вже на своєму місці) і зробимо такі ж порівняння та заміни місцями. 
    Наприкінці в передостанньому осередку в нас виявиться друге найбільше значення (99).

  • Повторимо цю роботу стільки разів, скільки в нас у масиві елементів мінус один.
Клас Arrays та його використання - 2Ідею ми вигадали, залишилося тільки написати код. Виглядатиме він так:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       for (int i = numbers.length - 1; i > 0; i--) {
           for (int j = 0; j < i; j++) {
           /*Порівнюємо елементи попарно,
             якщо вони мають неправильний порядок,
             то міняємо місцями*/
               if (numbers[j] > numbers[j + 1]) {
                   int tmp = numbers[j];
                   numbers[j] = numbers[j + 1];
                   numbers[j + 1] = tmp;
               }
           }
       }

   }
}
Еее… Виглядає дещо складно -_- Навіть якщо загальний принцип роботи зрозумілий, доводиться писати досить багато коду, щоб вирішити таку нескладну на вигляд завдання. Окей, може, ми просто переоцінабо себе? Напевно, завдання, яке ми взяли, поки що надто складне для нас. Давай спробуємо зробити що простіше. Наприклад, візьмемо той самий масив чисел.
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
Наше завдання – скопіювати його вміст в інший масив.
int [] numbersCopy = new int[10];
Подумай, як би ти це зробив, використовуючи знання про масиви, які в тебе вже є? Можна, наприклад, пройтися в циклі масивом numbersі по черзі записувати його елементи в numbersCopy:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = new int[10];

       for (int i = 0; i < numbers.length; i++) {

           numbersCopy[i] = numbers[i];
       }

   }
}
Ну-у-у, тут ми більш-менш впоралися! Завдання начебто вирішене, хоч знову ж таки: якщо його потрібно буде виконувати часто, у коді буде купа однакових циклів. Насправді ці та інші завдання вже давно вирішені творцями Java, і нам не потрібно "винаходити велосипед" і писати якийсь код власного рішення.

Клас Java Arrays

Вирішувати типові завдання під час роботи з масивами тобі допоможе спеціальний клас Java — Arrays. У цей клас були додані методи для вирішення найпоширеніших завдань, з якими стикаються Java-програмісти у роботі. Наприклад, завдання щодо сортування масиву, для якого ми самі намагалися придумати рішення, вирішується в один рядок:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       Arrays.sort(numbers);

       System.out.println(Arrays.toString(numbers));

   }
}
Метод Arrays.sort()виконує сортування масиву. Причому закладений у нього алгоритм робить це набагато ефективнішим за той код, який написали ми. Висновок на консоль:

[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
Зверніть увагу: для перетворення масиву в рядок ми використовували ще один метод класу Arrays- Arrays.toString(). Самі собою масиви в Java не перевизначають метод toString(). Тому якщо ти напишеш просто
System.out.println(numbers.toString());
буде викликаний метод toString()класу Object. У випадку з масивами висновок буде приблизно таким:

[I@4554617c
Не будемо зараз детально розбиратися, чому висновок саме такий, головне — це не те, що нам потрібно. А ось Arrays.toString() зробив те, що ми хотіли. До речі, наше завдання з копіюванням теж легко вирішується в класі Arrays:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOf(numbers, numbers.length);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
У метод Arrays.copyOf()ми передаємо наш оригінальний масив (з якого треба скопіювати значення) та довжину нового масиву, в який ми копіюємо дані. У разі як довжини ми вказали numbers.length, т.к. хочемо скопіювати масив повністю. Якщо ми хочемо скопіювати лише кілька перших елементів, можна вказати довжину для нового масиву менше:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOf(numbers, 4);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
Тут ми вказали довжину нового масиву, що дорівнює 4. Відповідно, тільки 4 перші елементи numbersбудуть скопійовані в новий масив. Виведення в консоль:

[167, -2, 16, 99]
До речі, якщо потрібно скопіювати частину масиву, але не з початку, а "з середини", Arraysдозволяє зробити це:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOfRange(numbers, 2,6);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
Висновок:

[16, 99, 26, 92]
У новий масив були скопійовані числа з осередків з другої ( включно ) по шосту ( не включно ). Крім того, нам може знадобитися порівняти два масиви між собою. Так само, як з методом toString(), самі собою масиви не перевизначають метод equals(). Тому якщо ми спробуємо порівняти їх так:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {1, 2, 3};
       int[] numbers2 = {1, 2, 3};

       System.out.println(numbers.equals(numbers2));
   }
}
отримаємо результат false. Адже буде викликаний метод Object.equals(), який порівнює посилання. А вони, звісно, ​​різні! Але нам треба порівняти вміст масивів, а не посилання. Клас Arraysмістить перевизначений метод equals(), який робить те, що нам потрібно:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {1, 2, 3};
       int[] numbers2 = {1, 2, 3};

       System.out.println(Arrays.equals(numbers, numbers2));
   }
}
Висновок:

true
До речі, клас Arraysуспішно працює не лише зі звичайними масивами, а й із двовимірними:
public class Main {

   public static void main(String[] args) {

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

       int[][] numbersCopy = Arrays.copyOf(numbers, numbers.length);

       System.out.println("Чи рівні ці двовимірні масиви між собою?");
       System.out.println(Arrays.deepEquals(numbers, numbersCopy));

       System.out.println(Arrays.deepToString(numbersCopy));
   }
}
Висновок:

Равны ли эти двумерные массивы между собой?
true
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Як бачиш, метод Arrays.copyOf()впорався з копіюванням та двовимірного масиву. Зверніть увагу, що в такому випадку при копіюванні двовимірного масиву відбувається так зване "поверхове копіювання". А для порівняння двовимірних масивів та їх виведення на консоль передбачені спеціальні методи - deepEqualsі deepToString(); У майбутньому ти ще не раз побачиш (і порадієш цьому), що творці Java передбачабо дуже багато типових ситуацій, з якими стикаються програмісти під час роботи, і реалізували в мові готові рішення для них. Використовувати ці рішення набагато простіше і зручніше, ніж винаходити велосипеди, чи не так? :) Обов'язково почитай документацію класу Arraysна сайті Oracle . Успіхів у навчанні!
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ