Java Collections Framework

Java Collections Framework (JCF) patrí k najpoužívanejším API v Jave, pretože poskytuje kolekciu všestranne použiteľných dátových štruktúr. Pri programovaní pracujeme s dátami, ktoré si ukladáme do vhodných dátových štruktúr v pamäti a tie potrebujeme najčastejšie kategorizovať, spracovať, triediť, filtrovať, resp. transformovať na inú formu dát.

Na našom blogu venovali dátovým štruktúram. Ak si naše články čítal/a, určite vieš, že naprogramovať efektívnu, optimalizovanú, znovu-použiteľnú dátovú štruktúru nie je vôbec jednoduchá úloha. To je jeden z dôvodov, prečo využívame frameworky, teda akúsi formu knižníc, ktorá už obsahuje predprogramované sady komponentov ihneď použiteľné v projektoch a programátor sa tak môže venovať na projekte špecifickej biznis logike.

A aby sme si nemuseli všetko naprogramovať sami na zelenej lúke, vysokoúrovňový programovací jazyk ako je napr. Java ponúka programátorom kolekciu optimalizovaných, univerzálne použiteľných dátových kontajnerov, do ktorých si svoje dáta môžu uložiť.

Pod kolekciou rozumieme zbierku typovo podobných objektov zoskupených do jednej dátovej štruktúry a používame ju na ukladanie, načítavanie, manipuláciu a komunikáciu s agregovanými dátami. Príkladom môže byť zoznam zákazníkov, mailový priečinok s obdržanými správami alebo telefónny adresár mapujúci mená klientov na ich telefónne čísla.

V tomto článku si vysvetlíme, ako vznikol Java Collections Framework, čo obsahuje a prečo by sme sa mali ihneď začať učiť používať všetky jeho benefity.

História Java Collections Framework

Framework kolekcií navrhol a vyvinul predovšetkým Joshua Bloch a bol predstavený v Jave 2 (JDK 1.2) v roku 1998. Ak si čítal/-a jednu z najlepších kníh o JavaEffective Java 3rd Edition, Joshua ti určite nie je neznámy. Hlavnou motiváciou bolo priniesť ľahko rozšíriteľný, adaptovateľný, vysoko-výkonný framework, ktorý by obsahoval sadu základných kolekcií (ako dynamické polia, spájané zoznamy, stromové štruktúry, hashovacie tabuľky, atď) a ich implementácia by bola veľmi efektívna a optimalizovaná na výkon.

Pred týmto vydaním boli vývojári odkázaní na zoskupovanie objektov cez pole, triedy VectorHashtable, ktoré nebolo jednoduché rozšíriť a neimplementovali jednotné rozhranie. Programátori si tak väčšinovo programovali vlastné dátové štruktúry, alebo siahli po nejakej neštandardnej knižnici tretích strán.

Postupne sa JCF vyvíjal a získaval nové funkcie. V Jave 5 boli pridané generické triedy, ktoré zvýšili typovú bezpečnosť kolekcií. Neskôr, s príchodom Javy 8, boli kolekcie rozšírené o streamy, lambda výrazy a možnosť funkcionálneho programovania, čo ešte viac zjednodušilo prácu s dátovými štruktúrami. Toto boli doteraz dve najdôležitejšie aktualizácie tohto frameworku, avšak na JCF sa stále pracuje a každá aktualizácia JDK prináša do kolekcií menšie, či väčšie vylepšenia.

Java Collections Framework hierarchia – architektúra

Framework kolekcií je zjednotená architektúra pre reprezentovanie a manipulovanie kolekcií. Skladá sa z troch častí: rozhrania, implementácie tried a algoritmy.

Rozhrania: Sú to abstraktné dátové typy (ADT), ktoré predstavujú kolekciu. Rozhrania umožňujú kolekciám, aby sa s nimi narábalo nezávisle od ich vnútornej reprezentácie. Sú dôležité, pretože umožňujú formovať hierarchiu tried.

Triedy: Tieto opakovateľne použiteľné štruktúry ponúkajú konkrétne implementácie rozhraní kolekcií.

Algoritmy: Výpočtové metódy na kolekciách ako sú napr. vyhľadávanie, triedenie alebo úpravu kolekcií.

Java Collections framework diagram
Java Collections framework diagram

Základné rozhrania JCF

Medzi najdôležitejšie rozhrania JCF, ktoré poskytujú všeobecnú štruktúru pre prácu s rôznymi typmi kolekcií, patria: Iterable, Collection, List, Queue, SetMap.

Rozhranie Iterable

Rozhranie Iterable je základné rozhranie v Jave, ktoré umožňuje iteráciu cez kolekciu objektov. Nachádza sa v balíku java.lang, je dostupné pre všetky kolekcie bez potreby importu. Kolekcie implementujúce Iterable môžu byť prechádzané pomocou cyklu for-each, ktoré výrazne zjednodušuje používanie. Rozhranie poskytuje jedinú metódu.

Metóda Popis
Iterator <E> iterator() Vráti pre kolekciu iterator typu E.

Rozhranie Iterator

Nachádza sa v balíku java.util. Aby sme mohli využívať iterator na prechádzanie kolekcie potrebujeme preťažiť (override) a poskytnúť implementáciu pre nasledovné metódy.

Metóda Popis
boolean hasNext() Vráti true, ak má iterácia viac prvkov.
E next() Vráti ďalší prvok E v iterácii
void remove() Odstráni posledný prvok vrátený iterátorom (voliteľná operácia).

Rozhranie Collection

Základné rozhranie, ktoré predstavuje skupinu objektov. Je rodičom špecializovaných rozhraní, ako sú List, Set a Queue, pre ktoré definuje radu abstraktných metód (to znamená, že k dispozícii je iba signatúra metódy), ktoré podriadené kolekcie musia naimplementovať. Vďaka tomu je práca s kolekciami podobná a intuitívna. Nachádza sa v balíku java.util, podobne ako všetky podriadené kolekcie.

Metóda Popis
boolean add(E e) Pridá zadaný prvok do kolekcie (voliteľná operácia).
void clear() Odstráni všetky prvky z tejto kolekcie (voliteľná operácia).
boolean contains(Object o) Vráti true, ak táto kolekcia obsahuje zadaný prvok.
boolean equals(Object o) Porovná zadaný objekt s touto kolekciou kvôli rovnosti.
boolean isEmpty() Vráti sa true, ak táto kolekcia neobsahuje žiadne prvky.
Iterator<E> iterator() Vráti iterátor nad prvkami v tejto kolekcii.
boolean remove(Object o) Odstráni jednu inštanciu zadaného prvku z tejto kolekcie, ak je prítomná (voliteľná operácia).
int size() Vráti počet prvkov v tejto kolekcii.
Object[] toArray() Vráti pole obsahujúce všetky prvky v tejto kolekcii.

Rozhranie List

Definuje rozhranie pre kolekcie, kde záleží na poradí prvkov (tzv. ordered collections) a môžu obsahovať duplicitné elementy. Pri prístupe k prvkov sa využíva prístup na báze indexov, cez ktoré sa určuje ich pozícia v kolekcii.

Príklady implementácií tohto rozhrania sú kolekcie ArrayList, LinkedList, Vector, Stack.

Rozhranie Set

Definuje rozhranie pre kolekcie, ktoré obsahujú množinu unikátnych prvkov bez duplicít. Elementy nie sú ukladané v žiadnom konkrétnom poradí (tzv. unordered collections). Avšak niektoré implementácie ako LinkedHashSet udržiava poradie vkladania prvkov. Vloženie jedného null elementu do tejto kolekcie Množina je povolené napr. u kolekcie HashSet, ale niektoré implementácie ako TreeSet vkladanie null prvkov neumožňujú.

Príklady implementácií tohto rozhrania sú kolekcie HashSet, TreeSet a LinkedHashSet.

Rozhranie Queue

Definuje rozhranie pre kolekcie, ktoré by mali byť spracované podľa FIFO (First In, First Out) princípu, aj keď niektoré varianty implementácie ako sú prioritné fronty sa nemusia tohto pridržiavať.

Príklady implementácií tohto rozhrania sú kolekcie LinkedList, PriorityQueue a ArrayDequeue.

Rozhranie Map

Toto rozhranie patrí do JCF, ale nemá žiadny vzťah s rozhraním Collection, ktoré pracuje s jednou entitou, zatiaľ čo rozhranie Map pracuje s dvomi – unikátnym kľúčom a jeho príslušným objektom. Napr. kľúčom môže byť telefónne číslo a objektom majiteľ daného telefónu. Pre získanie objektu z kolekcie Mapa potrebujeme zvyčajne použiť jeho kľúč.

Príklady implementácií tohto rozhrania sú kolekcie HashMap, TreeMap a LinkedHashMap.

Odporúčame ti...

Rad by som ešte spomenul, že tento článok nespomína všetky kolekcie, ktoré nám Java Collections Framework ponúka a ak ti nejaká kolekcia pre tvoje špecifické zadanie alebo problém chýba, odporúčam pred vlastnou implementáciou kolekcie (čo je tiež možné riešenie) si pozrieť aktuálnu JCF dokumentáciu.

Za zmienku ešte stojí, že s príchodom JDK21 sa v JEP431 objavili tri nové rozhrania pre vytváranie sekvenčných kolekcií (SequencedCollection), sekvenčných množín (SequencedSet) a sekvenčných máp (SequencedMap).

Algoritmy

JCF obsahuje aj množstvo algoritmov na manipuláciu s kolekciami. Tieto algoritmy sú implementované ako statické metódy v triede Collections. Medzi najdôležitejšie patria:

  • Triedenie: Pomocou metódy sort je možné zoradiť kolekciu podľa prirodzeného poradia alebo na základe komparátora.
  • Hľadanie: Algoritmy ako binarySearch umožňujú efektívne vyhľadávanie prvkov v zoradenej kolekcii.
  • Úpravy: Algoritmy ako reverse, shuffle a rotate umožňujú rôzne transformácie kolekcií.
  • Synchronizácia: Pomocou metód ako synchronizedList je možné vytvoriť bezpečné verzie kolekcií pre viacvláknové spracovanie.

Výhody Java Collections Framework

Zosumarizujme si ešte benefity, ktoré nám JCF ponúka:

  • Optimalizované kolekcie na vysoký výkon a množstvo dát (elementov kolekcií).
  • Implementácie kolekcií sú si podobné (vďaka hierarchií rozhraní a tried).
  • Šetrí čas potrebný na implementáciu a odladenie vlastných dátových štruktúr a algoritmov.
  • Uľahčuje opätovné použitie kódu.

Záver

Java Collections Framework nám ponúka obrovské množstvo rozhraní, tried a algoritmov na najrozličnejšie spektrum vývojárskych výziev, ktoré súvisia s efektívnou prácou s dátovými štruktúrami a dátami v Jave. Aj keď je náročné na začiatku zvládnuť jeho komplexnosť, investícia času do pochopenia JCF sa vývojárom z dlhodobého hľadiska len a len vyplatí.

O autorovi

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Daj nám o sebe vedieť