3. diel - Zoznam (List) pomocou poľa v Jave
V minulej lekcii, Java Collections Framework , sme sa pozreli, ako má jazyk Java implementované kolekcia v rámci Java Collections Frameworku. Dnes sa budeme v Java tutoriálu venovať prvú kolekciu, zoznamom (listom). To je typ kolekciou, s ktorým sme sa počas kurzu už stretli.
Poľa
Urobme si na začiatku malú odbočku späť k poľu, ktoré bolo prvé "kolekciou", ktorú sme v seriáli spoznali. Pole sa vyznačuje tým, že má pevne daný počet prvkov. Z tohto dôvodu niekedy ani nebýva považované za kolekciu, pretože nespĺňa časť ich definície. Prvky v poli sú číselne indexované a to od nuly.
Hlavnou nevýhodou poľa teda je, že do neho nemôžeme za behu aplikácie prvky pridávať alebo ich mazať. To bohužiaľ často potrebujeme, aj keď sú situácie, kedy je pole ideálna voľba. Touto daní je vyvážená obrovská rýchlosť, s ktorou môžeme s prvkami poľa pracovať. Keďže dáta sú rovnakého typu (či už úplne rovnakého, alebo spoločného predka), zaberajú v pamäti rovnako miesta. Jednotlivé prvky poľa sú v pamäti uložené za sebou, ako v rade, ktorá je neprerušená. Pole celých čísel si môžeme predstaviť napr. Nasledovne:
Ak teda chceme napr. Pristúpiť na 5. prvok, len vstúpime tam, kde pole
začína, a potom odskočíme 4 násobky veľkosti typu (tu int
u)
ďalej. Sme na 5. prvku. Čítanie a zápis na indexy v poli má teda
konštantný časovú zložitosť. Ak vás tento termín zmiatol, môžete to
chápať tak, že do poľa zapisujeme okamžite a rovnako tak z neho aj
čítame.
Ak v Jave založíme prázdnej číselné pole, je automaticky naplnené nulami.
Zoznamy (Listy)
Zoznamy (anglicky a často i slovensky Listy) sú kolekcie, ktoré umožňujú prvky za behu programu pridávať a mazať. Môžu byť číselne indexované ako polia, ale tiež nemusí. Sú v zásade 2 typy zoznamov.
Zoznamy s poľom
Zoznam najčastejšie využíva toho, že hoci veľkosť poľa nemôžeme za behu programu meniť, môžeme za behu vytvoriť pole nové.
Zoznam je potom trieda, ktorá obsahuje metódy pre pridanie a odstránenie
prvkov (a mnoho ďalších, pre nás teraz nepodstatných metód). Trieda v
podstate obaľuje pole a obsahuje navyše premennú, kde si uchováva počet
prvkov. Pri vytvorení inštancie sa vytvorí pole napr. O 12tich prvkoch a
premenná s počtom prvkov sa nastaví na 0
. Pri pridaní prvého
prvku sa prvok vloží na 1. index v poli a počet prvkov sa inkrementuje. Takto
môžeme pridať až 12 prvkov, než polia naplníme. Vo chvíli, keď
vyčerpáme kapacitu poľa, jednoducho vytvoríme nové, treba 2x väčší.
Prvky zo starého poľa do neho skopírujeme a staré polia zahodíme. Až sa
toto nové pole opäť naplní, budeme situáciu opakovať. Takýmto spôsobom
naozaj interne funguje kolekcie ArrayList
, s ktorou sme doteraz
pracovali. ArrayList
si môžeme predstaviť asi takto:
Zoznam na obrázku má 8 prvkov. Prvky sú uložené v internom poli, ktoré má prvkov 12. Posledné 4 prvky sa nevyužívajú a zoznam sa zvonku tvária, ako že tam nie sú.
Výhodou je rýchlosť prístupu k prvkom pomocou indexov vďaka využitiu poľa. Nevýhodou je samozrejme časové oneskorenie potrebná na vytvorenie nového poľa a prekopírovanie prvkov, aj keď nastáva len občas. Ďalšie, aj keď menej bolestivú nevýhodou, je, že kolekcia zaberá v pamäti viac priestoru, než je nutné. Tento typ zoznamu je napriek tomu najpoužívanejší kolekcií v Jave a je pomerne dobre optimalizovaný.
Zoznam s poľom je teda v Jave zastúpený triedou ArrayList
. Na
obrázku nižšie je vidieť kompletný hierarchia triedy
ArrayList
:
Ako vidíme, ArrayList
implementuje okrem iného rozhranie
List
.
Metódy a ďalšie prvky na triede List
Popíšme si dôležité metódy na tomto rozhraní. List
tvorí
základ pre všetky zoznamy v Jave a obsahuje najmä tieto metódy:
add()
- Pridá nový prvok do listu.addAll()
- Pridá viac nových prvkov do listuclear()
- Vymaže všetky prvky.contains()
- Vrátitrue
, ak list obsahuje daný prvok.toArray()
- Metóda skopíruje prvky z listu do poľa.remove()
- Vymaže daný prvok. Táto funkcia je veľmi užitočná v prípade, že máme v liste inštancie nejakej triedy (napr. Používateľa), nemusíme si držať ich číselné indexy, len zavoláme napr.list.remove(karel)
, kedy odovzdáme konkrétnu inštanciu, ktorá sa má odstrániť zo zoznamu .removeAll()
- Vymaže viac daných prvkov.count()
- Vráti počet prvkov v poli.
Metóda add()
má dve preťaženie. V jednom prípade prijíma
iba pridávaný objekt, v druhom prípade prijíma ešte index, na ktorý sa má
prvok vložiť. Metóda remove()
má tiež dve preťaženie. Raz
prijíma objekt, ktorý sa má odstrániť, v prípade druhom prijíma index, na
ktorom má prvok odstrániť.
Hoci sme si ArrayList
vyskúšali už 1000krát, pre úplnosť
si predsa len ukážme niekoľko riadkov kódu:
List<Integer> list = new ArrayList<>(); list.add(5); list.add(10); System.out.println(list.get(0));
Výstup programu:
5
Kód vyššie vytvorí ArrayList
typu Integer
,
pridá do neho 2 čísla a potom vypíše prvý prvok do konzoly. Pracujeme s
indexy akoby sme pracovali s poľom, ale môžeme do neho za behu programu
pridávať prvky a tiež je mazať.
Všimnite si, že používame zoznam typu Integer
na ukladanie typov int
. V Jave nie je možné typovo
generický typ primitívnym dátovým typom, ako je byte
,
short
, int
, long
, boolean
,
char
, float
alebo double
. Namiesto toho
je potrebné použiť tzv. Obalové triedy (wrappery), ktoré boli vytvorené
práve na účely použitia týchto typov v kolekciách. Konverzia medzi
primitívnymi dátovými typmi a ich obalovými triedami prebieha
automaticky.
Ďalej List
ponúka metódy:
indexOf()
- Vráti index prvého výskytu daného prvku v liste.lastIndexOf()
- Obdoba metódyindexOf()
, vracia index posledného výskytu daného prvku v liste.removeIf()
- Odstráni všetky prvky, ktoré zodpovedajú danej podmienke (predikátu, pozri ďalej v kurze).sort()
- Setřídí list. Je dôležité, aby jeho prvky implementovali rozhraniaComparable
, inak metóda vyvolá výnimku. Základné triedy a štruktúry z Javy rozhraniaComparable
implementujú, u svojich tried ho vieme dodať.
Až na niekoľko metód sme si popísali celý ArrayList
.
Vyskúšajte si ďalšie metódy ako sort()
a podobne.
Detailnejšie prácu s kolekciami sa budeme ešte venovať, až sa dostaneme k
technológii Stream API.
V budúcej lekcii, Kvíz - Genericita, zoznam a spojový zoznam v Jave , si uvedieme druhý typ zoznamu, ktorým je spájať zoznam.
V nasledujúcom kvíze, Kvíz - Genericita, zoznam a spojový zoznam v Jave, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 224x (1.98 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java