Масив об'єктів в Java
⚡ Розумний підсумок
Масив об'єктів в 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 під час виконання.
Крок 5) Розкоментуйте рядки 4 та 5. Ці два рядки створюють реальні Account об'єкти та призначити їх obj[0] та obj[1]Масив тепер містить реальні посилання, і код виконується чисто.
вихід:
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
Окрім ініціалізації на основі сеттерів, показаної вище, масив об'єктів можна ініціалізувати трьома більш зрозумілими способами. Кожен стиль жертвує багатослівністю заради ясності, тому оберіть той, який найкраще відповідає ситуації.
- Ініціалізація циклу — виділити масив, потім пройтися по кожному індексу та призначити новий об'єкт. Це стандартний шаблон для великих масивів або коли кількість об'єктів динамічна.
- Ініціалізація конструктора — передавати значення безпосередньо конструктору під час створення, тому окремий виклик сеттера не потрібен.
- Ініціалізація літералів масиву — оголошувати та заповнювати в одному операторі з вбудованим рядком
{ ... }ініціалізатор, ідеально підходить для невеликих фіксованих наборів.
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 у більшості повсякденних програмних кодів, оскільки можливість додавання та видалення без перерозподілу переважує невеликі накладні витрати на кожен елемент.



