Kurs Java

Kolekcje - Wprowadzenie

W ramach kursu swego czasu stworzyliśmy rozdział Tablice obiektów i typów prostych. Napisaliśmy wtedy, że tablice służą do przechowywania wielu elementów w ramach jednego obiektu. W ten sposób możemy na przykład grupowo przechowywać lub transportować obiekty tego samego typu. Zresztą wygląda to tak samo jak w naszym życiu codziennym. Nikt nie przynosi do domu po jednym obiekcie ziemniaka, tylko zwykle wkładamy je do siatki i przynosimy wszystkie naraz. Oczywiście w przypadku siatki nie ma znaczenia kolejność ziemniaków, co jest akurat dosyć istotnym elementem w przypadku tablic. Niemniej można powiedzieć, że takie zbieranie obiektów w grupy jest bardzo praktycznym podejściem i niezwykle często używanym w programowaniu.

Problem z tablicami

Tablice mają jednak swoje poważne mankamenty i raczej nie są obecnie popularnym sposobem na przechowywanie danych w Javie. Podstawowym problemem jest potrzeba znajomości rozmiaru tablicy już w trakcie jej tworzenia, przez co niemożliwe jest dynamiczne dokładanie do niej elementów bez tworzenia kopii tablicy o rozmiarze większym niż poprzednia tablica.
Item[] itemArr = new Item[2];
itemArr[0] = new Item();
itemArr[1] = new Item();
Item[] newItemArr = Arrays.copyOf(itemArr, itemArr.length + 1);
newItemArr[2] = new Item();
Problemów z tablicami jest nieco więcej. Na szczęście Java dostarcza nam inne rozwiązanie, które jest wygodniejsze i bardziej eleganckie w użyciu, o którym piszemy już w kolejnym paragrafie.

Kolekcje

Temat ten jest niezwykle ważny i absolutnie każdy programista Javy musi dobrze go poznać. Samo grupowe przechowywanie danych to tak naprawdę tylko zajawka tego co dają nam kolekcje. W zależności od rodzaju kolekcji bardzo istotne są zagadnienia takie jak choćby kolejność lub unikalność jej elementów. Zacznijmy jednak od początku.

W Javie istnieje pakiet o nazwie java.util, w którym znajduje się interfejs Collection. Interfejs ten jest nadrzędnym interfejsem wszystkich rodzajów kolekcji, ale out of the box nie jest implementowany przez żadną klasę JDK. Dopiero interfejsy podrzędne (dziedziczące) posiadają wbudowane klasy, dostarczające implementacje metod. W celu łatwiejszego zrozumienia najlepiej jest zerknąć na obrazek przedstawiający hierarchię interfejsów:
Eclipse - Nowy projekt
Interfejs Collection, oprócz tego że stoi na szczycie hierarchii jest przy okazji dostawcą większości metod, z których korzystają dziedziczące interfejsy. Do metod tych należą między innymi: add (dodawanie do kolekcji), remove (usuwanie z kolekcji), clear (czyszczenie kolekcji), size (zwracanie rozmiaru kolekcji).

Zobaczmy teraz czym charakteryzują się poszczególne interfejsy.
  • List

    Najczęściej używany rodzaj kolekcji. Charakteryzuje się tym, że jej elementy posiadają określoną kolejność. Dodatkowo są one indeksowane, dzięki czemu można pobrać obiekt znajdujący się na konkretnej pozycji (indeksie) w liście. Na przykład możemy użyć metody get(2), gdzie 2 to numer pozycji, którą chcemy pobrać. Dostaniemy wtedy trzeci element listy (pozycje są numerowane od 0). Interfejs jest implementowany przez następujące klasy:
    • ArrayList
    • LinkedList
    • Vector (ta klasa jest jeszcze rozszerzana przez Stack, który nie implementuje bezpośrednio interfejsu List)
  • Queue

    Najważniejszą cechą tej kolejki jest zachowanie kolejności według zasady FIFO (First In - First Out). Oznacza to, że pierwszy element wprowadzony do kolejki będzie z niej również pobierany jako pierwszy. Interfejs jest implementowany przez:
    • PriorityQueue
  • Deque (Double ended queue)

    Kolejki te, zgodnie z nazwą, wspierają zarówno FIFO jak i LIFO (Last In - First Out). To drugie oznacza, że ostatni element wprowadzony do kolejki będzie z niej pobierany jako pierwszy. W tym miejscu warto sobie wyobrazić stos, na którym układamy kolejne elementy, by później zdejmować je począwszy od tego na samej górze i potem dalej w dół. Interfejs jest implementowany przez:
    • ArrayDeque
    • LinkedList (ta klasa implementuje zarówno interfejs List jak i Deque)
  • Set

    Najważniejszą cechą tego rodzaju kolekcji jest unikalność jej elementów. Porówananie obiektów następuje przez wykorzystanie metody equals. W zbiorze nigdy nie będą istniały dwa obiekty (ani więcej), dla których metoda ta zwraca wartość true. Sety nie posiadają numerowanych pozycji w postaci indeksów. Zatem nie odwołamy się tutaj do konkretnej pozycji celem pobrania obiektu. Interfejs jest implementowany przez klasy:
    • HashSet
    • LinkedHashSet (rozszerza klasę HashSet, ale implementuje też bezpośrednio interfejs Set)
  • SortedSet

    Zbiory posortowane mają dokładnie te same cechy co "zwykłe" zbiory, z tym że dodatkowo zapewniają one kolejność elementów. Sortowanie odbywa się na podstawie wykorzystania specjalnej metody, o której jeszcze nie mówiliśmy, ale która pojawi się w niedługim czasie w naszym kursie. Interfejs jest implementowany przez:
    • TreeSet
Appa Notka. Na pierwszy rzut oka liczba możliwości może trochę zniechęcać. Na pocieszenie możemy powiedzieć, że na początku wystarczy opanować klasy ArrayList i HashSet. Są to najczęściej wykorzystywane klasy w projektach. Oczywiście z upływem czasu należy kontynuować naukę kolejnych klas.
Szukasz dobrego kursu nowej Javy? Mamy dla Ciebie kurs oparty na 150 przykładach.
Kurs od Javy 8 do 14
Kurs nowej Javy składa się z kursu Javy 8 oraz Javy od wersji 9 do 17.

Iterable

W tym miejscu przyszedł czas na małą dygresję związaną ze strukturą przedstawioną powyżej. Okazuje się, że interfejs Collection nie jest całkowicie niezależnym bytem. Dziedziczy on z jeszcze innego interfejsu o nazwie Iterable. Dzięki temu wszystkie wymienione kolekcje mogą być przeglądane pozycja po pozycji w ramach pętli. Mówimy wtedy, że iterujemy po kolejnych elementach kolekcji, a to pozwala nam na wykonywanie operacji na kolejnych elementach. Frameworki (na przykład Spring) często operują w swoich metodach na parametrach implementujących interfejs Iterable. Warto to zapamiętać!

Kolekcje par

Na początek mała uwaga. Kolekcje, o których mówiliśmy do tej pory faktycznie wywodzą się z jednego wspólnego interfejsu Collection. Te, o których będziemy mówić teraz nie posiadają tej cechy i patrząc tylko z tego punktu widzenia można stwierdzić, że kolekcjami nie są. Jednakże ich cechy charakterystyczne, takie jak to, że stanowią grupę obiektów oraz to, że możemy przechodzić po obiektach tej grupy w sposób iteracyjny (choć nie wywodzą się z interfejsu Iterable) powoduje, że zwyczajowo je również nazywamy kolekcjami. Jest to zgadanienie poruszane dosyć często podczas rozmów kwalifikacyjnych.
Eclipse - Nowy projekt
Przyjrzyjmy się czym charakteryzują się poszczególne interfejsy.
  • Map

    Mapy przechowują kolekcję par, a dokładnie pary klucz-wartość. Każdy klucz w mapie jest unikalny, a wartości są przypisane tym kluczom. Wartości nie są unikalne. Mogą być przypisane do wielu kluczy. Jeśli korzystamy z implementacji interfejsu Map, to nie mamy zapewnionej kolejności elementów. Interfejs jest implementowany przez klasę:
    • HashMap (ta klasa jest jeszcze rozszerzana przez LinkedHashMap )
  • SortedMap

    Interfejs posiada wszystkie przedstawione własności co Map plus dodatkowo zapewnia odpowiedni porządek sortowania. Jest on implementowany przez klasę:
    • TreeMap
Appa Notka. Mapy są bardzo często wykorzystywane w Javie. Najpopularniejszą z nich jest klasa HashMap i to od niej warto rozpocząć naukę. Po zapoznaniu się z "haszmapą" z łatwością zrozumiesz pojęcie TreeMap.
Na koniec, dodajmy jeszcze, że Map nie rozszerza interfejsu Iterable. Zawiera za to metody, które umożliwiają operowanie na interfejsach Set (dla kluczy) oraz Collection (dla wartości), ale o tym będziemy już mówić w jednym z kolejnych rozdziałów.
Zdjęcie autora
Autor: Jarek Klimas
Data: 03 stycznia 2024
Labele: Backend, Podstawowy, Java
Masz pytanie dotyczące tego rozdziału? Zadaj je nam!
Masz pytanie dotyczące prezentowanego materiału?
Coś jest dla Ciebie niejasne i Twoje wątpliwości przeszkadzają Ci w pełnym zrozumieniu treści?
Napisz do nas maila, a my chętnie znajdziemy odpowiednie rozwiązanie.
Najciekawsze pytania wraz z odpowiedziami będziemy publikować pod rozdziałem.
Nie czekaj. Naucz się programować jeszcze lepiej.
kursjava@javappa.com

Stale się rozwijamy, a więc bądź na bieżąco!
Na ten adres będziemy przesyłać informacje o ważniejszych aktualizacjach, a także o nowych materiałach pojawiających się na stronie.
Polub nas na Facebooku:
Nasi partnerzy: stackshare
Javappa to również profesjonalne usługi programistyczne oparte o technologie JAVA. Jeśli chesz nawiązać z nami kontakt w celu uzyskania doradztwa bądź stworzenia aplikacji webowej powinieneś poznać nasze doświadczenia.
Kliknij O nas .


Pozycjonowanie stron: Grupa TENSE