JavaRush /Blog Java /Random-PL /Klasa ArrayList w Javie

Klasa ArrayList w Javie

Opublikowano w grupie Random-PL
Cześć! W poprzednich wykładach szczegółowo badaliśmy taką strukturę danych jak tablica i przyglądaliśmy się typowym przykładom pracy z nimi. Ale ta struktura danych ma wiele wad. Odpowiedzią na nie w Javie było pojawienie się ArrayList. Mówiąc najprościej, ArrayList w Javie to „ulepszona” tablica z wieloma nowymi funkcjami.Klasa ArrayList - 1

Czym różni się Java Arraylist od zwykłych tablic?

Generalnie tablice są dość wygodne i jak już zauważyłeś można z nimi zrobić mnóstwo rzeczy :) Tablice mają jednak też sporo wad.
  • Ograniczony rozmiar. Już na etapie tworzenia tablicy musisz wiedzieć, ile komórek powinna ona zawierać. Jeśli nie docenisz wymaganej ilości, nie będzie wystarczającej ilości miejsca. Jeśli przecenisz, tablica pozostanie w połowie pusta i nie jest tak źle. W końcu okazuje się, że przeznaczysz na to również więcej pamięci niż to konieczne.
  • Tablica nie ma metod dodawania elementów. Zawsze musisz jawnie określić indeks komórki, do której chcesz dodać element. Jeśli przypadkowo określisz już zajętą ​​komórkę z żądaną wartością, zostanie ona nadpisana.
  • Nie ma metod usunięcia elementu. Wartość można jedynie „wyzerować”.
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Tomasz");
       cats[1] = new Cat("Hipopotam");
       cats[2] = new Cat(„Filip Markowicz”);

       cats[1] = null;



       System.out.println(Arrays.toString(cats));
   }

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Wniosek:

[Cat{name='Томас'}, null, Cat{name='ФLubпп Маркович'}]
Wszystkie te niedociągnięcia można wyeliminować za pomocą ArrayList. Tworzy się go bardzo prosto:
ArrayList<Cat> cats = new ArrayList<Cat>();
Teraz stworzyliśmy listę do przechowywania obiektów Cat. Zwróć uwagę:nie określamy rozmiaru ArrayList, ponieważ jest ona automatycznie rozwijana. Jak to jest możliwe? Łatwo. Zdziwisz się, ale ArrayList opiera się na zwykłej tablicy :) Tak, wewnątrz niej znajduje się tablica, w której przechowywane są nasze elementy. Ale ArrayList ma specjalny mechanizm pracy z nim:
  • Kiedy ta wewnętrzna tablica jest pełna, ArrayList tworzy w sobie nową tablicę. Jego rozmiar = (rozmiar starej tablicy * 1,5) +1.
  • Wszystkie dane zostaną skopiowane ze starej tablicy do nowej
  • Stara tablica jest usuwana przez moduł zbierający elementy bezużyteczne.
Dzięki temu mechanizmowi ArrayList (w przeciwieństwie do tablicy) implementuje metodę dodawania nowego elementu. To jest metoda add().
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Hipopotam"));
}
Nowy element zostanie dodany na końcu listy. Teraz nie ma już ryzyka przepełnienia, więc mechanizm ten jest w pełni bezpieczny. Nawiasem mówiąc, ArrayList może nie tylko wyszukiwać obiekt według indeksu, ale także odwrotnie - może znaleźć indeks obiektu w ArrayList poprzez odniesienie do obiektu! W tym celu implementuje metodę indexOf(): Podajemy do niego link do żądanego obiektu, a indexOf()on zwraca nam swój indeks:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
Wniosek:

0
Zgadza się, obiekt thomasjest faktycznie przechowywany w komórce 0. Tablice mają nie tylko wady, ale także niewątpliwe zalety. Jednym z nich jest wyszukiwanie elementu po indeksie. Ponieważ wskazujemy na indeks, czyli na konkretny adres w pamięci, takie przeszukiwanie tablicy jest bardzo szybkie. ArrayList w Javie też może to zrobić! Aby to zrobić, implementuje metodę get():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
Wniosek:

Cat{name='Бегемот'}
Możesz także łatwo sprawdzić, czy ArrayList zawiera określony obiekt, czy nie. Odbywa się to za pomocą metody contains():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   cats.remove(pushok);
   System.out.println(cats.contains(pushok));
}
Metoda sprawdza, czy element znajduje się w wewnętrznej tablicy ArrayList i zwraca wynik w postaci boolean- truelub false. Wniosek:

false
I kolejna ważna rzecz dotycząca wkładania. ArrayList umożliwia wstawienie danych nie tylko na końcu tablicy, ale także do dowolnej komórki według indeksu. Ma na to dwie metody:
  • add(int index, Cat element)
  • set(int index, Cat element)
Do obu przekazujesz indeks komórki, do której chcesz wstawić, oraz link do samego obiektu. Różnica polega na tym, że wklejenie set()zastępuje starą wartość przechowywaną w komórce. Wstawienie przez add()pierwsze powoduje przesunięcie wszystkich elementów począwszy od [index]końca tablicy i dodanie potrzebnego obiektu do wynikowej pustej komórki. Oto przykład:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.set(0, philipp);//Teraz mamy listę 2 kotów. Dodajemy 3. przez zestaw:

   System.out.println(cats.toString());
}
Wniosek:

[[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='ФLubпп Маркович'}, Cat{name='Бегемот'}]
Mieliśmy listę 2 kotów, metodą set()do komórki wstawiliśmy kolejnego 0. W rezultacie stara wartość przechowywana w tej komórce została zastąpiona nową.
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.add(0, philipp);//Teraz mamy listę 2 kotów. Dodaj trzeci przez add

   System.out.println(cats.toString());
}
Ale to add()działało inaczej. Przesunął wszystkie elementy w prawo i następnie wpisał nową wartość do komórki 0. Wniosek:

[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='ФLubпп Маркович'}, Cat{name='Томас'}, Cat{name='Бегемот'}]
Aby całkowicie wyczyścić listę, użyj metody clear():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   cats.clear();

   System.out.println(cats.toString());
}
Wniosek:

[]
Cała zawartość została usunięta z listy. Przy okazji, zwróć uwagę: w przeciwieństwie do tablic, w ArrayList metoda toString() jest nadpisana i natychmiast wyświetla listę w formacie string. W przypadku tablic musieliśmy do tego użyć klasy Arrays. A skoro przypomnieliśmy sobie Arrays: w Javie można łatwo „przełączać się” pomiędzy tablicą a ArrayList, czyli konwertować jedną na drugą. Klasa Arrays ma do tego metodę Arrays.asList(). Za jego pomocą pobieramy zawartość tablicy w postaci listy i przekazujemy ją konstruktorowi naszej ArrayList:
public static void main(String[] args) {

   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   Cat[] catsArray = {thomas, behemoth, philipp, pushok};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
Wniosek:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='ФLubпп Маркович'}, Cat{name='Пушок'}]
Możesz także zrobić odwrotnie - uzyskać tablicę z obiektu ArrayList. Aby to zrobić, użyj metody toArray():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();

   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   Cat[] catsArray = cats.toArray(new Cat[0]);

   System.out.println(Arrays.toString(catsArray));
}
Uwaga: przekazaliśmy pustą tablicę do metody toArray(). To nie jest błąd. Wewnątrz klasy ArrayList metoda ta jest zaimplementowana w taki sposób, że przekazanie pustej tablicy zwiększa jej wydajność. Na razie zapamiętaj to na przyszłość (ale możesz też przenieść konkretny rozmiar, będzie działać). Mówiąc o rozmiarze. Aktualny rozmiar listy można sprawdzić metodą size():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   System.out.println(cats.size());
}
Należy tutaj zrozumieć, że w przeciwieństwie do lengthwłaściwości array metoda ArrayList.size() zwraca dokładnie liczbę elementów, a nie początkową pojemność, ponieważ nie określamy jej podczas tworzenia ArrayList. Nawiasem mówiąc, ogólnie można to wskazać. ArrayList ma odpowiedni konstruktor. Ale jego zachowanie w zakresie dodawania nowych elementów nie ulegnie zmianie:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>(2);// utwórz ArrayList o początkowej pojemności 2


   Cat thomas = new Cat("Tomasz");
   Cat behemoth = new Cat("Hipopotam");
   Cat philipp = new Cat(„Filip Markowicz”);
   Cat pushok = new Cat("Puch");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   System.out.println(cats.size());
}
Wyjście konsoli:

4
Stworzyliśmy listę z 2 elementami, ale kiedy jej potrzebowaliśmy, łatwo ją rozbudowywano. Inna sprawa, że ​​jeśli początkowo stworzyliśmy bardzo małą listę, to będzie ona musiała częściej przeprowadzać operację rozszerzania, a to pochłania pewną ilość zasobów. W tym wykładzie ledwo poruszyliśmy proces usuwania elementów z listy ArrayList. Oczywiście nie jest to spowodowane zapomnieniem. Temat ten został wydzielony na osobny wykład, z którym możecie zapoznać się dalej :)
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION