JavaRush /Java блог /Random UA /Кава-брейк #176. Подібності та відмінності між Array та A...

Кава-брейк #176. Подібності та відмінності між Array та ArrayList. Як написати ефективний метод equals()

Стаття з групи Random UA

Подібності та відмінності між Array та ArrayList

Джерело: Medium Зміст цієї статті присвячений розумінню концепцій масиву (Array) та ArrayList, а також відмінностей між ними. Кава-брейк #176.  Подібності та відмінності між Array та ArrayList.  Як написати ефективний метод equals() - 1

Масив Java

Масив ( Array ) - це структура даних, яка дозволяє зберігати впорядковану послідовність значень одного типу. Наприклад, можна створити масив символів, чисел і так далі. Це стосується всіх примітивних типів і навіть для таких об'єктів, як String . Після створення масиву ми можемо змінити його розмір. Ось загальний приклад оголошення змінного посилання на масив та виділення масиву:
dataType[] arrayName = new dataType[numElements];
Якщо ми намагаємося додати більше розміру масиву, то отримуємо виняток ArrayIndexOutOfBoundsException .

Оголошення масиву

Для оголошення масиву використовуються символи [] після типу даних. Вони вказують, що змінна є посиланням на масив. Посилальна змінна масиву може посилатися на масиви різних розмірів. Ключове слово New створює місце в пам'яті для зберігання масиву з певною кількістю елементів. Посилальна змінна масиву призначається для посилання цей знову виділений масив. У наступному прикладі оголошується змінна посилання на масив gameScores , виділяється масив з чотирьох цілих чисел і призначається gameScores для посилання на виділений масив.
int[] gameScores = new int[4];
Елементи масиву автоматично ініціалізуються значеннями за умовчанням під час використання ключового слова new для ініціалізації посилання на масив. Значення за умовчанням для елементів цілих (integer) типів даних і типів даних з плаваючою комою дорівнює нулю, а значення за умовчанням для логічних елементів дорівнює false . Ви також можете оголосити змінну масиву посилань, не виділяючи відразу масив, а потім призначити змінну з виділеним масивом.
int[] gameScores;

gameScores = new int[4];

Ініціалізація масиву зі значеннями, відмінними від значень за умовчанням

Ви можете ініціалізувати елементи масиву значеннями, відмінними від значень за замовчуванням, вказавши початкові значення у фігурних дужках {} , розділених комами.
int [] myArray = { 5 , 7 , 11 };
У наведеному вище прикладі створюється масив з трьох цілих елементів зі значеннями 5, 7 і 11. Така ініціалізація масиву не вимагає використання ключового слова new , оскільки розмір масиву автоматично встановлюється рівною кількістю елементів у фігурних дужках. Для великих масивів ініціалізацію можна виконати спочатку визначивши масив, а потім використовуючи цикл для призначення елементів масиву. Доступ до елементів масиву можна отримати, використовуючи їх індекси, що починаються з нуля.
Int[ ] intArray = new int [ ] {2};
intArray [0] = 1;
intArray [1] = 2;

ArrayList

ArrayList — це впорядкований список елементів типу посилання з змінним розміром . Також це клас із пакету java.util , що належить Java Collection Framework. ArrayList надає нам динамічні масиви та автоматично обробляє зміну їхнього розміру. У міру додавання елементів до списку ArrayList , обсяг його пам'яті автоматично збільшується. Використовувати ArrayList можна за допомогою оператора import java.util.ArrayList; . Також ми можемо створити екземпляр ArrayList , використовуючи наступний оператор:
ArrayList<Type> arrayList = new ArrayList<Type>();
Розмір списку ArrayList може збільшитись, щоб підтримувати розміщення потрібних елементів. ArrayList не підтримує примітивні типи, такі як int , а підтримує типи посилань, такі як Integer . Поширеною помилкою серед новачків є оголошення ArrayList примітивного типу, такого як int , як ArrayList<int> myVals . Це призводить до помилки компіляції: "unexpected type, found: int, required: reference". Приклад: Створимо об'єкт ArrayList з ім'ям cars , в якому зберігатимуться рядки:
import java.util.ArrayList;

ArrayList<String> cars = new ArrayList<String>();
Для додавання елементів ArrayList використовується метод add() . Щоб отримати доступ до ArrayList , використовується метод get() .
cars.add("Tesla");
cars.add("BMW");
cars.add("Kia");
cars.get(0);
Різниця між вбудованим масивом і масивом ArrayList Java полягає в тому, що в першому випадку розмір масиву не можна змінити (якщо ви хочете додати або видалити елементи в/з масиву, вам потрібно створити новий). Тоді як ArrayList елементи можуть бути додані і видалені будь-коли.

Подібності між масивом і ArrayList

  • Array та ArrayList використовуються для зберігання елементів.
  • Array та ArrayList можуть зберігати нульові значення.
  • Обидва процеси відбуваються у постійному часі.
  • Вони можуть мати значення, що повторюються.
  • Array та ArrayList не гарантують наявність упорядкованих елементів.

Ключові відмінності між Array та ArrayList

Основна відмінність між масивом ( Array ) і ArrayList полягає у статичній природі масиву та динамічній природі ArrayList . Після створення ви не можете змінити розмір масиву, тоді як ArrayList може змінити розмір за необхідності. Ще одна важлива відмінність полягає в тому, що масив - це базова функціональність Java. З іншого боку, ArrayList є частиною структури колекцій Java. Ми можемо отримати доступ до елементів масиву, використовуючи квадратну дужку, в якій ми можемо вказати індекс. У той час як для доступу до елементів ArrayList та їх зміни існує набір методів. Незважаючи на те, що вони різні, обидва вони, однак, можна порівняти за іншими параметрами. Обидві ці структури даних Java засновані на індексах і дозволяють зберігати об'єкти. Крім того, вони допускають нульові значення та дублікати. Якщо ви знаєте розмір об'єктів заздалегідь, то краще використовувати масив. Але якщо ви не впевнені в розмірі, замість цього слід використовувати ArrayList .

Як написати ефективний метод equals()

Джерело: Medium Ця публікація допоможе вам краще дізнатися про застосування методу equals() під час роботи з кодом Java. Якщо говорити про метод equals() за умовчанням і без будь-якої реалізації, він багато в чому схожий на операцію == . Тобто цей метод порівнює об'єкти. Наприклад, equals() порівнює два рядки і повертає true якщо рядки рівні, і false , якщо ні. Врахуйте, що операція == не рекомендується для порівняння об'єктів Java. Причина в тому, що при порівнянні об'єктів == поверне true тільки якщо посилання вказують на той самий об'єкт. Найпростіший спосіб уникнути проблем: не перевизначати метод equals , у цьому випадку кожен екземпляр класу дорівнює лише самому собі. Перевизначати equals потрібно лише тоді, коли клас має поняття логічної рівності , яке відрізняється від простої ідентичності об'єкта, а суперклас ще не перевизначив рівність. Таким чином, при використанні методу equals() потрібно з'ясувати, чи є посилання на об'єкти логічно еквівалентними і не посилаються вони на один і той же об'єкт.

Властивості методу equals

Кожен метод equals реалізує відношення еквівалентності . Він має такі властивості:
  • Рефлексивний (Reflexive) : для будь-якого ненульового значення посилання x функція x.equals(x) повинна повертати true .

  • Симетричний (Symmetric) : для будь-яких ненульових значень посилань x і y функція x.equals(y) повинна повертати значення true лише тоді, коли y.equals(x) повертає значення true .

  • Перехідний (Transitive) : Для будь-яких ненульових значень посилань x , y , z , якщо x.equals(y) повертає true , і y.equals(z) повертає true , то x.equals(z) також повинен повертати true .

  • Послідовний (Consistent) : для будь-яких ненульових значень посилань x і y багаторазові виклики x.equals(y) повинні постійно повертати true або послідовно повертати false .

  • Ненульова (Non-nullity) : Для будь-якого ненульового значення посилання x функція x.equals(null) повинна повертати false .

Давайте детальніше розглянемо кожну властивість:

Рефлексивність:

Об'єкт повинен дорівнювати самому собі. Щоб переконатися в цьому, додайте екземпляр класу до колекції. Метод contains цілком може показати, що колекція не містить екземпляра, який ви щойно додали.

Симетрія:

Два об'єкти (вони можуть бути з різних класів) повинні дорівнювати один одному.

Послідовність:

Не пишіть метод equals , який залежить від ненадійних/змінних ресурсів.

Ненульовий:

Завжди повертає true якщо об'єкт, переданий в equals , має значення null .

Підбиваємо підсумки:

Ось рецепт якісного методу equals :
  1. Використовуйте оператор == , щоб перевірити, чи аргумент є посиланням на цей об'єкт.

  2. Використовуйте оператор instanceof , щоб перевірити, чи має аргумент правильний тип.

  3. Наведіть аргумент до правильного типу.

  4. Для кожного “значного” поля в класі перевірте, чи це поле аргументу відповідає полю цього об'єкта:

    • Для примітивних полів: чий тип не є float або double , використовуйте оператор == для порівнянь.
    • Для полів посилань на об'єкти: - рекурсивно викликайте метод equals; для полів із плаваючою комою використовуйте статичний метод Float.compare(float, float); а для подвійних полів використовуйте Double.compare (double, double) .
    • Для полів масиву: застосуйте ці поради до кожного елемента. Якщо кожен елемент у полі масиву значущий, використовуйте один із методів Arrays.equals() .
    • Деякі поля посилань на об'єкти можуть містити значення null . Щоб уникнути виключення NullPointerException , перевіряйте такі поля на рівність за допомогою статичного методу Objects.equals(Object, Object) .
  5. Коли ви закінчите писати свій метод equals , задайте собі три питання: Чи є він симетричним? Чи він транзитивний (перехідний)? Він послідовний?

І пам'ятайте, завжди перевизначайте hashCode при перевизначенні equals .
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ