Масив об'єктів в Java

⚡ Розумний підсумок

Масив об'єктів в Java зберігає посилання на об'єкти у суміжному слоті фіксованого розміру, дозволяючи одній змінній зберігати багато екземплярів класу та отримувати доступ до кожного з них через індекс для ітерації, мутації та передачі методам.

  • 📦 Зберігання довідок: Кожен слот у Java Масив об'єктів містить посилання на об'єкт, а не на сам об'єкт, подібно до будь-якої об'єктної змінної в Java.
  • 🧱 Двоетапне створення: Виділіть масив з новим ClassName[size], потім виділіть кожен об'єкт з новим ClassName() перед викликом методів для нього.
  • ⚠️ Виняток NullPointer: Кожен слот починається з null. Виклик методу для неініціалізованого слота викликає виняток NullPointerException під час виконання.
  • 🔁 Ітерація: Використовуйте цикл for з довжиною масиву або розширений цикл for, щоб пройтися по кожному об'єкту в масиві.
  • 📏 Фіксований розмір: Масив не може збільшуватися після виділення пам'яті. Використовуйте ArrayList, коли кількість об'єктів змінюється під час виконання.
  • 🏗️ Ініціалізація конструктора: Конструктори, що передаються вбудовано під час створення, забезпечують коротше та безпечніше налаштування, ніж виклики методів встановлення після виконання.
  • 🚚 Параметр методу: Передача масиву методу передає посилання, тому зміни всередині методу видно тому, хто викликає.

Масив об'єктів в Java

Що таке масив об'єктів у Java?

A Java масив об'єктів зберігає кілька екземплярів об'єктів одного класу в одному контейнері фіксованого розміру. На відміну від примітивного масиву, який зберігає такі значення, як int, doubleабо boolean безпосередньо в кожному слоті зберігається масив об'єктів посиланняКожен слот вказує на місце розташування об'єкта в пам'яті, а сам об'єкт знаходиться там. Java купа.

Цей макет відповідає тому, як будь-який об'єкт змінна in Java працює. Масив просто групує кілька посилань на об'єкти разом, щоб ви могли отримати до них доступ за індексом. Це природний вибір, коли кількість об'єктів відома заздалегідь і не змінюється протягом життя програми.

синтаксис

ClassName[] obj = new ClassName[array_length];

Права сторона виділяє простір для array_length посилання, всі ініціалізовані до nullЖодного об'єкта ClassName поки що існує, лише контейнер, який може містити посилання на такі об'єкти.

Як створити масив об'єктів у Java

Створення робочого масиву об'єктів завжди відбувається у два кроки виділення. Перший виділяє контейнер посилань, а другий виділяє кожен об'єкт, на який вказуватиме контейнер. Пропуститиping другий крок є найпоширенішим джерелом NullPointerException у початківців Java Код.

Крок 1) Відкрийте свій редактор коду та скопіюйте наступний код:

class ObjectArray {
    public static void main(String args[]) {
        Account obj[] = new Account[2];
        // obj[0] = new Account();
        // obj[1] = new Account();
        obj[0].setData(1, 2);
        obj[1].setData(3, 4);
        System.out.println("For Array Element 0");
        obj[0].showData();
        System.out.println("For Array Element 1");
        obj[1].showData();
    }
}

class Account {
    int a;
    int b;

    public void setData(int c, int d) {
        a = c;
        b = d;
    }

    public void showData() {
        System.out.println("Value of a = " + a);
        System.out.println("Value of b = " + b);
    }
}

Крок 2) Збережіть файл як ObjectArray.java, а потім скомпілювати та запустити його.

Крок 3) Зверніть увагу на помилку. Спробуйте її налагодити, перш ніж переходити до кроку 4.

Крок 4) Перевірте лінію Account obj[] = new Account[2];Він виділяє масив із двох посилальних змінних типу Account, але він не виділяє жодних Account предмети. Обидва слоти вміщують nullі дзвінок obj[0].setData(...) на null посилання викидає NullPointerException під час виконання.

Java Масив об'єктів, що посилаються на змінні

Крок 5) Розкоментуйте рядки 4 та 5. Ці два рядки створюють реальні Account об'єкти та призначити їх obj[0] та obj[1]Масив тепер містить реальні посилання, і код виконується чисто.

Java Масив об'єктів заповнено

вихід:

For Array Element 0
Value of a = 1
Value of b = 2
For Array Element 1
Value of a = 3
Value of b = 4

Як ініціалізувати масив об'єктів у Java

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

  1. Ініціалізація циклу — виділити масив, потім пройтися по кожному індексу та призначити новий об'єкт. Це стандартний шаблон для великих масивів або коли кількість об'єктів динамічна.
  2. Ініціалізація конструктора — передавати значення безпосередньо конструктору під час створення, тому окремий виклик сеттера не потрібен.
  3. Ініціалізація літералів масиву — оголошувати та заповнювати в одному операторі з вбудованим рядком { ... } ініціалізатор, ідеально підходить для невеликих фіксованих наборів.
class Account {
    int a, b;

    public Account(int a, int b) {   // constructor
        this.a = a;
        this.b = b;
    }
}

public class InitDemo {
    public static void main(String[] args) {

        // 1) Loop initialisation
        Account[] loopArr = new Account[3];
        for (int i = 0; i < loopArr.length; i++) {
            loopArr[i] = new Account(i, i * 10);
        }

        // 2) Constructor initialisation, one slot at a time
        Account[] ctorArr = new Account[2];
        ctorArr[0] = new Account(1, 2);
        ctorArr[1] = new Account(3, 4);

        // 3) Array literal initialisation
        Account[] litArr = {
            new Account(5, 6),
            new Account(7, 8),
            new Account(9, 10)
        };

        System.out.println("loop size   = " + loopArr.length);
        System.out.println("ctor size   = " + ctorArr.length);
        System.out.println("literal size= " + litArr.length);
    }
}

Ініціалізація циклу є найбезпечнішою за замовчуванням, оскільки гарантує, що не залишиться жодного слота. nullІніціалізація конструктора робить намір явним, коли кожному об'єкту потрібні різні аргументи, а літерали масивів зберігають компактність невеликого демонстраційного коду. Не змішуйте стилі в одному масиві, якщо у вас немає на це причини: узгодженість полегшує виявлення помилок.

Ітерація та доступ до елементів у Java Масив об'єктів

Після заповнення масиву об'єктів три шаблони покривають майже всі потреби доступу. Виберіть стиль циклу, який відповідає тому, наскільки код повинен контролювати індекс.

Classic for петля надає доступ до індексу, що корисно для заміни елементів, порівняння сусідніх елементів або ітерації піддіапазону.

for (int i = 0; i < obj.length; i++) {
    System.out.println("Element " + i);
    obj[i].showData();
}

Розширення for петля (цикл «for-each») приховує індекс та читається природніше, коли індекс не потрібен:

for (Account acc : obj) {
    acc.showData();
}

Потоки (Java 8 років і пізніше) перетворити масив у конвеєр, що зручно для фільтрації, мапуванняping, або агрегування без написання циклу:

import java.util.Arrays;

Arrays.stream(obj)
      .filter(acc -> acc.a > 0)
      .forEach(Account::showData);

Щоб прочитати або оновити окремий елемент, використовуйте прямий доступ до індексу, наприклад obj[1].setData(10, 20)Завжди спочатку перевіряйте довжину за допомогою obj.length уникати ArrayIndexOutOfBoundsExceptionКоли будь-який слот може бути null, захистіть доступ за допомогою перевірки на нульове значення або Optional щоб програма продовжувала працювати, а не зависала.

Масив об'єктів проти ArrayList об'єктів у Java

Простий масив об'єктів є швидким та передбачуваним, але його фіксований розмір стає обмеженням, щойно кількість об'єктів змінюється під час виконання. JavaАвтора Рамки колекцій забезпечує ArrayList як динамічну альтернативу. У таблиці нижче показано, коли кожен варіант є доречним.

особливістьМасив об'єктівArrayList об'єктів
РозмірВиправлено під час створенняАвтоматично зростає та зменшується
ДеклараціяAccount[] a = new Account[5];List<Account> list = new ArrayList<>();
Елемент доступуa[i]list.get(i)
Додати елементНе підтримується після створенняlist.add(obj)
Тип безпекиТипізація під час компіляції за допомогою оголошенняДженерики, що застосовуються під час компіляції
продуктивністьТрохи швидше індексоване читанняАмортизована сума O(1), деякі накладні витрати на елемент
Бажано, колиРозмір відомий і фіксованийРозмір невідомий або змінюється під час виконання

Використовуйте масив, коли обмежений обсяг пам'яті та передбачуване індексування мають значення, наприклад, у матричних макетах або критично важливих для продуктивності гарячих шляхах. ArrayList у більшості повсякденних програмних кодів, оскільки можливість додавання та видалення без перерозподілу переважує невеликі накладні витрати на кожен елемент.

Поширені запитання

Масив об'єктів у Java — це контейнер фіксованого розміру, який зберігає посилання на екземпляри одного й того ж класу. Кожен слот вказує на об'єкт у купі, а доступ до елементів здійснюється за допомогою індексу, що починається з нуля, з використанням квадратних дужок.

Оголосіть масив за допомогою ClassName[] arr = new ClassName[size], потім створіть кожен об'єкт за допомогою new ClassName() у циклі або за допомогою вбудованого літерала масиву. Обидва кроки обов'язкові; перший виділяє лише слоти для посилань.

Оскільки new ClassName[size] виділяє пам'ять лише для самого масиву. Кожен слот починається з null, тому виклик будь-якого методу для цього слота викидає NullPointerException. Виправте це, призначивши новий ClassName() кожному індексу перед використанням.

Масив має фіксований розмір, який вибирається під час створення, тоді як ArrayList збільшується та зменшується автоматично. Масиви забезпечують трохи швидше індексоване зчитування; ArrayList додає зручні методи додавання, видалення та потокової передачі для повсякденного коду додатків.

Використовуйте класичний цикл for з arr.length, коли вам потрібен індекс, або розширений цикл for-each для простої ітерації. Для фільтрації або перетворення обгорніть масив за допомогою Arrays.stream(arr) та з'єднайте потрібний вам конвеєр.

Оголосіть параметр як ClassName[], а потім викличте метод зі змінною масиву. Java передає посилання на масив за значенням, тому зміни полів елементів всередині методу видно тому, хто їх викликає.

Генератори коду машинного навчання розпізнають двоетапний шаблон розподілу та доповнюють відсутні нові рядки ClassName(), які забувають новачки. Вони також пропонують ArrayList, коли розмір цільової колекції невідомий, що зменшує помилки NullPointerException.

Так. GitHub Copilot генерує оголошення масивів, цикли конструкторів, блоки ітерацій та перетворення ArrayList з коментаря, що описує модель домену. RevПерегляньте згенерований код для коректних аргументів конструктора та безпечної обробки null-значень перед використанням.

Підсумуйте цей пост за допомогою: