Tablica obiektów w Java

⚡ Inteligentne podsumowanie

Tablica obiektów w Java przechowuje odwołania do obiektów w stałym, ciągłym slocie, umożliwiając pojedynczej zmiennej przechowywanie wielu instancji klasy i dostęp do każdej z nich poprzez indeks w celu iteracji, mutacji i przekazywania do metod.

  • 📦 Pamięć referencyjna: Każdy slot w Java tablica obiektów zawiera odwołanie do obiektu, a nie sam obiekt, podobnie jak każda zmienna obiektu w Java.
  • 🧱 Tworzenie dwuetapowe: Przydziel tablicę za pomocą nowej ClassName[size], a następnie przydziel każdy obiekt za pomocą nowej ClassName() przed wywołaniem na nim metod.
  • ⚠️ Wyjątek NullPointerException: Każdy slot na początku ma wartość null. Wywołanie metody na niezainicjowanym slocie powoduje wyjątek NullPointerException w czasie wykonywania.
  • 🔁 Iteracja: Użyj pętli for o długości tablicy lub rozszerzonej pętli for, aby przejść przez każdy obiekt w tablicy.
  • 📏 Stały rozmiar: Tablica nie może się rozrastać po alokacji. Użyj ArrayList, gdy liczba obiektów zmienia się w czasie wykonywania.
  • 🏗️. Inicjalizacja konstruktora: Konstruktory przekazywane inline podczas tworzenia zapewniają krótszą i bezpieczniejszą konfigurację niż wywołania setterów post-hoc.
  • 🚚 Parametr metody: Przekazanie tablicy do metody powoduje przeniesienie odniesienia, dzięki czemu zmiany wewnątrz metody są widoczne dla wywołującego.

Tablica obiektów w Java

Czym jest tablica obiektów w Java?

A Java tablica obiektów Przechowuje wiele instancji obiektów tej samej klasy w jednym kontenerze o stałym rozmiarze. W przeciwieństwie do tablicy prymitywnej, która przechowuje wartości takie jak int, doublelub boolean bezpośrednio w każdym slocie przechowywana jest tablica obiektów referencjeKażdy slot wskazuje na lokalizację obiektu w pamięci, a sam obiekt znajduje się na Java sterta.

Ten układ pasuje do każdego obiektu zmienna in Java Działa. Tablica po prostu grupuje kilka referencji do obiektów, aby można było uzyskać do nich dostęp za pomocą indeksu. Jest to naturalny wybór, gdy liczba obiektów jest znana z góry i nie zmienia się w trakcie działania programu.

Składnia

ClassName[] obj = new ClassName[array_length];

Prawa strona wyznacza przestrzeń dla array_length odniesienia, wszystkie zainicjowane do null. Żaden obiekt ClassName istnieje jeszcze tylko kontener, który może przechowywać odniesienia do takich obiektów.

Jak utworzyć tablicę obiektów w Java

Utworzenie działającej tablicy obiektów zawsze wymaga dwóch kroków alokacji. Pierwszy z nich to alokacja kontenera referencyjnego, a drugi to alokacja każdego obiektu, na który będzie wskazywał kontener. Pomińping drugi krok jest najczęstszym źródłem NullPointerException dla początkujących Java kod.

Krok 1) Otwórz swoje edytor kodu i skopiuj poniższy kod:

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);
    }
}

Krok 2) Zapisz plik jako ObjectArray.java, a następnie skompiluj i uruchom.

Krok 3) Zanotuj błąd. Spróbuj go zdebugować, zanim przejdziesz do kroku 4.

Krok 4) Sprawdź linię Account obj[] = new Account[2];. Przydziela tablicę dwóch zmiennych referencyjnych typu Account, ale nie przydziela żadnych Account obiekty. Oba sloty mieszczą nulli dzwoniąc obj[0].setData(...) na null odniesienie rzuca NullPointerException W czasie wykonywania.

Java Zmienne referencyjne tablicy obiektów

Krok 5) Odkomentuj wiersze 4 i 5. Te dwa wiersze tworzą prawdziwe Account obiekty i przypisać je do obj[0] oraz obj[1]Tablica zawiera teraz prawdziwe odwołania, a kod działa poprawnie.

Java Tablica obiektów wypełniona

Wyjście:

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

Jak zainicjować tablicę obiektów w Java

Oprócz inicjalizacji opartej na setterach, pokazanej powyżej, tablicę obiektów można zainicjować na trzy bardziej przejrzyste sposoby. Każdy styl rezygnuje z rozwlekłości na rzecz przejrzystości, więc wybierz ten, który najlepiej pasuje do sytuacji.

  1. Inicjalizacja pętli — przydziel tablicę, a następnie przejrzyj każdy indeks i przypisz nowy obiekt. To standardowy schemat dla dużych tablic lub sytuacji, gdy liczba obiektów jest dynamiczna.
  2. Inicjalizacja konstruktora — przekazuj wartości bezpośrednio do konstruktora w momencie tworzenia, dzięki czemu nie jest potrzebne oddzielne wywołanie settera.
  3. Inicjalizacja literału tablicy — zadeklaruj i wypełnij w jednym poleceniu z wbudowanym { ... } inicjator, idealny dla małych, stałych zestawów.
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);
    }
}

Inicjalizacja pętli jest najbezpieczniejszą domyślną opcją, ponieważ gwarantuje, że nie zostanie pominięty żaden slot nullInicjalizacja konstruktora sprawia, że ​​intencja jest jawna, gdy każdy obiekt potrzebuje różnych argumentów, a literały tablicowe pozwalają zachować zwartość kodu demonstracyjnego. Nie mieszaj stylów w obrębie tej samej tablicy, chyba że masz ku temu powody: spójność ułatwia wykrycie błędów.

Iterowanie i uzyskiwanie dostępu do elementów w Java Tablica obiektów

Po zapełnieniu tablicy obiektów, trzy wzorce pokrywają niemal wszystkie potrzeby dostępu. Wybierz styl pętli, który odpowiada temu, ile kontroli nad indeksem potrzebuje kod.

Klasyczny for pętla udostępnia dostęp do indeksu, który jest przydatny przy zastępowaniu elementów, porównywaniu sąsiadujących elementów lub iterowaniu podzakresu.

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

Ulepszone for pętla (pętla „for-each”) ukrywa indeks i odczytuje go bardziej naturalnie, gdy nie jest potrzebny:

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

Strumienie (Java 8 i nowsze) przekonwertować tablicę na potok, który jest przydatny do filtrowania, mapowaniapinglub agregowanie bez pisania pętli:

import java.util.Arrays;

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

Aby odczytać lub zaktualizować pojedynczy element, skorzystaj na przykład z bezpośredniego dostępu do indeksu obj[1].setData(10, 20)Zawsze najpierw sprawdź długość obj.length unikać ArrayIndexOutOfBoundsException. Kiedy jakikolwiek slot może być null, zabezpiecz dostęp za pomocą kontroli zerowej lub Optional aby utrzymać działanie programu, zamiast go zawieszać.

Tablica obiektów kontra lista obiektów ArrayList w Java

Prosta tablica obiektów jest szybka i przewidywalna, ale jej stały rozmiar staje się ograniczeniem, gdy tylko liczba obiektów zmienia się w czasie wykonywania. JavaStruktura kolekcji zapewnia ArrayList jako dynamiczna alternatywa. Poniższa tabela pokazuje, kiedy każdy wybór jest właściwy.

CechaTablica obiektówArrayList obiektów
RozmiarNaprawiono w momencie utworzeniaRośnie i kurczy się automatycznie
DeklaracjaAccount[] a = new Account[5];List<Account> list = new ArrayList<>();
Element dostępua[i]list.get(i)
Dodaj elementNieobsługiwane po utworzeniulist.add(obj)
Wpisz bezpieczeństwoTypowanie w czasie kompilacji według deklaracjiTypy generyczne wymuszane w czasie kompilacji
WydajnośćNieznacznie szybsze odczyty indeksowaneZamortyzowane O(1) dodaje, pewne narzuty na element
Preferowane, gdyRozmiar jest znany i ustalonyRozmiar jest nieznany lub zmienia się w czasie wykonywania

Użyj tablicy, gdy liczy się ograniczona pamięć i przewidywalne indeksowanie, na przykład w układach macierzowych lub ścieżkach krytycznych pod względem wydajności. ArrayList w większości codziennego kodu aplikacji, ponieważ możliwość dodawania i usuwania bez realokacji przeważa nad niewielkim narzutem na element.

FAQ

Tablica obiektów w Java to kontener o stałym rozmiarze, który przechowuje referencje do instancji tej samej klasy. Każdy slot wskazuje na obiekt na stercie, a dostęp do elementów odbywa się poprzez indeksowanie od zera za pomocą nawiasów kwadratowych.

Zadeklaruj tablicę za pomocą ClassName[] arr = new ClassName[size], a następnie utwórz każdy obiekt za pomocą new ClassName() w pętli lub z wbudowanym literałem tablicowym. Oba kroki są wymagane; pierwszy przydziela tylko sloty referencyjne.

Ponieważ new ClassName[size] przydziela tylko samą tablicę. Każdy slot na początku jest nullem, więc wywołanie dowolnej metody na tym slocie powoduje wyjątek NullPointerException. Aby to naprawić, przypisz new ClassName() do każdego indeksu przed użyciem.

Tablica ma stały rozmiar wybrany podczas tworzenia, podczas gdy ArrayList rośnie i kurczy się automatycznie. Tablice zapewniają nieco szybsze odczyty indeksowane; ArrayList oferuje wygodne metody dodawania, usuwania i strumieniowania do codziennego kodu aplikacji.

Użyj klasycznej pętli for z parametrem arr.length, gdy potrzebujesz indeksu, lub rozbudowanej pętli for-each do prostej iteracji. W celu filtrowania lub transformacji, opakuj tablicę za pomocą Arrays.stream(arr) i utwórz potrzebny potok.

Zadeklaruj parametr jako ClassName[] name, a następnie wywołaj metodę ze zmienną tablicową. Java przekazuje odwołanie do tablicy przez wartość, więc mutacje pól elementów wewnątrz metody są widoczne dla wywołującego.

Generatory kodu uczenia maszynowego rozpoznają dwuetapowy wzorzec alokacji i uzupełniają brakujące wiersze ClassName(), o których zapominają początkujący. Sugerują również ArrayList, gdy rozmiar kolekcji docelowej jest nieznany, redukując błędy NullPointerException.

Tak. GitHub Copilot generuje deklaracje tablic, pętle konstruktora, bloki iteracyjne i konwersje ArrayList na podstawie komentarza opisującego model domeny. Revwygenerował kod pod kątem poprawnych argumentów konstruktora i bezpiecznego przetwarzania wartości null przed użyciem.

Podsumuj ten post następująco: