– Już jestem.

– Cześć, Basiu!

– Dzisiaj porozmawiamy o czymś bardzo ciekawym. Opowiem Ci o klasie ArrayList.

– Nowa klasa? Super! Co ona może robić?

– Pozwól, że zacznę od pewnej historii. Jedyną rzeczą, jakiej programiści nie lubią w tablicach, jest brak możliwości zmiany jej rozmiaru. Co zrobisz, jeśli będziesz musiał dodać do tablicy trzy elementy, a będzie tylko jedno wolne miejsce?

– Jedynym rozwiązaniem jest tworzenie dużych tablic, żeby mieć gwarancję miejsca dla potencjalnych, nowych elementów. To jednak oznacza marnowanie pamięci. Jeśli tablica zazwyczaj zawiera trzy elementy i istnieje szansa, że będziesz musiał tam umieścić 100 elementów, to musisz utworzyć 100-elementową tablicę.

– Jak zatem rozwiązali to programiści?

– Napisali klasę ArrayList, która robi to samo co tablica, ale można zmieniać jej rozmiar.

– Interesujące posunięcie. Jak tego dokonali?

– Każdy obiekt ArrayList przechowuje zwyczajną tablicę złożoną z elementów. Kiedy czytasz elementy z ArrayList, są one czytane z jej wewnętrznej tablicy. Kiedy dopisujesz je do ArrayList, są one dopisywane do jej wewnętrznej tablicy. Proszę, porównaj te kolumny:

Tablica ArrayList
Utwórz kontener dla elementów
String[] lista = new String[10];
ArrayList<String> lista = new ArrayList<String>();
Pobierz liczbę elementów
int n = lista.length;
int n = lista.size();
Pobierz element z tablicy/kolekcji
String s = lista[3];
String s = lista.get(3);
Zapisz element w tablicy
lista[3] = s;
lista.set(3, s);

– Dlaczego zatem ArrayList jest lepsza? Z tego, co ja widzę, kod jest teraz dłuższy.

– Po pierwsze, ArrayList umożliwia przeprowadzanie różnych dodatkowych operacji przez programistów. Zwykła tablica nie daje takiej możliwości. Na przykład możemy zastąpić lub usunąć elementy ze środka tablicy bez zostawiania pustych miejsc.

– Po drugie, mamy możliwość zmiany rozmiaru tablicy. Kiedy potrzebujesz dodać jeden element więcej, a wewnętrzna tablica nie ma wolnych miejsc, wewnątrz ArrayList jest to przeprowadzane w następujący sposób:

a) Tworzona jest następna tablica, która jest 50% większa niż bieżąca wewnętrzna tablica plus jeden element.

b) Wszystkie elementy ze starej tablicy zostają skopiowane do nowego.

c) Nowa tablica zostaje zapisana jako wewnętrzna tablica obiektu ArrayList. Stara tablica jest deklarowany jako nieużytek (po prostu przestajemy przechowywać do niej referencję).

Tablica ArrayList
Dodaj element na końcu tablicy
To działanie nie jest obsługiwane
lista.add(s);
Dodaj element w środku tablicy
To działanie nie jest obsługiwane
lista.add(15, s);
Dodaj element na początku tablicy
To działanie nie jest obsługiwane
lista.add(0, s);
Usuń element z tablicy
Możemy usunąć element przy użyciu lista[3] = null. Ale to zostawi „dziurę” w tablicy.
lista.remove(3);
undefined
2
Zadanie
Składnia Java, poziom 7, lekcja 5
Niedostępne
Wprowadzanie kodu
Nie musisz myśleć, po prostu go wyklep! Brzmi to trochę paradoksalnie, ale czasami Twoje palce „pamiętają” kod lepiej niż Twój świadomy umysł. Właśnie dlatego trening w tajnym centrum CodeGym zawiera zadania wymagające wprowadzania kodu. Wprowadzając kod, przyzwyczajasz się do składni oraz zarabiasz ciemną materię. Co więcej, walczysz z własnym lenistwem!

– Jak się pracuje z ArrayList?

– Właściwie tak samo, jak ze zwyczajną tablicą. Spójrz. Porównajmy pracę z ArrayList i tablicą. Załóżmy, że potrzebujemy 'wczytać 10 ciągów i wyświetlić je na ekranie w odwrotnej kolejności'.

– Spójrz na to:

Użycie tablicy
public static void main(String[] args)
{
Reader r = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(r);

// Czyta ciągi z klawiatury
String[] lista = new String[10];
for (int i = 0; i < lista.length; i++)
{
  String s = reader.readLine();
  lista[i] = s;
}

// Wyświetla zawartość tablicy
for (int i = 0; i < lista.length; i++)
{
  int j = lista.length - i - 1;
  System.out.println( lista[j] );
}
}
Użycie ArrayList
public static void main(String[] args)
{
Reader r = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(r);

// Czyta ciągi z klawiatury
ArrayList<String> lista = new ArrayList<String>();
for (int i = 0; i < 10; i++)
{
  String s = reader.readLine();
  lista.add(s);
}

// Wyświetl zawartość kolekcji
for (int i = 0; i < lista.size(); i++)
{
  int j = lista.size() - i - 1;
  System.out.println( lista.get(j) );
}
}

Zaznaczyłem tym samym kolorem podobne działania w każdej kolumnie.

– Z jednej strony, wszystko jest inne. A z drugiej, pozostaje takie samo.

– Racja. Poza tym, że nie używamy nawiasów kwadratowych podczas pracy z ArrayList. Zamiast tego używamy metod get, set i add.

– Tak, to zrozumiałem. A jednak wciąż wygląda to bardzo podobnie.