5. diel - Viacrozmerné polia v Jave
Dnešný tutoriál je v kurze základných konštrukcií Javy v podstate bonusový a pojednáva o tzv. viacrozmerných poliach. Teoreticky môžete rovno prejsť k objektovo orientovanému programovaniu, odporúčam však si koniec tejto sekcie ešte aspoň prejsť, aby ste mali o zostávajúcich technikách povedomia, predsa len sa jedná o dosť základné vedomosti.
Už vieme pracovať s jednorozmerným poľom, ktoré si môžeme predstaviť ako riadok priehradiek v pamäti počítača.
(Na obrázku je vidieť pole ôsmich čísel)
Hoci to nie je tak časté, v programovaní sa občas stretávame aj s viacrozmernými poľami a to najmä ak programujeme nejakú simuláciu (napr. hru).
Dvojrozmerné pole
Dvojrozmerné pole si môžeme v pamäti predstaviť ako tabuľku a mohli by sme takto reprezentovať napr. rozohranú partiu piškvoriek. Ak by sme sa chceli držať reálnych aplikácií, ktoré budete neskôr v zamestnaní tvoriť, môžeme si predstaviť, že do 2D poľa budeme ukladať informácie o obsadenostiach sedadiel v kinosále. Situáciu by sme si mohli graficky znázorniť napr. takto:
(Na obrázku je vidieť 2d pole reprezentujúce obsadenosť kinosály)
Kinosála by bola v praxi samozrejme väčšia, ale ako ukážka nám toto
pole postačí. 0
znamená voľno, 1
obsadené.
Neskôr by sme mohli doplniť aj 2
– rezervované a podobne. Pre
tieto stavy by bolo správnejšie vytvoriť si vlastný dátový typ, tzv.
zoznam, ale s ním sa stretneme až neskôr, takže si teraz musíme vystačiť
iba s číslami.
Java v skutočnosti neposkytuje žiadnu dodatočnú podporu pre viacrozmerné polia, môžeme si ich však jednoducho deklarovať ako pole polí. Definícia takého poľa pre kinosála by vyzerala takto:
Prvá číslica udáva počet stĺpcov, druhá počet riadkov (samozrejme si to môžeme určiť aj obrátene, napr. matice v matematike sa zapisujú opačne).
Všetky číselné polia v Jave sú po deklarácii automaticky inicializované samými nulami, môžeme sa na to spoľahnúť. Vytvorili sme si teda v pamäti tabuľku plnú núl.
Naplnenie dátami
Teraz kinosálu naplníme jednotkami tak, ako je vidieť na obrázku
vyššie. Pretože budeme ako správni programátori leniví, využijeme na
vytvorenie riadku jedničiek for
cykly:) Pre prístup k prvku 2D
poľa musíme samozrejme zadať 2 súradnice.
Výpis
Výpis poľa opäť vykonáme pomocou cyklu, na 2d pole budeme potrebovať cykly 2 (jeden nám proiteruje stĺpce a druhý riadky). Ako správni programátori nevložíme počet riadkov a stĺpcov do cyklov napevno, pretože sa môže zmeniť.
Musíme však pamätať na skutočnosť, že keď sa spýtame na
kinosal.length
, bude obsahovať počet stĺpcov (presnejšie
dĺžku vonkajšieho poľa, ktoré predstavuje stĺpce). Aby sme získali počet
riadkov (dĺžku vnútorného poľa, ktoré stĺpec reprezentuje), spýtame sa
na kinosal[0].length
. Všimnite si, že na to v poli musí byť
teda aspoň jeden riadok.
Cykly zanoríme do seba tak, aby nám vonkajší cyklus prechádzal riadkami a vnútornými stĺpcami v aktuálnom riadku. Po výpise riadku je nutné odriadkovať. Oba cykly musia mať samozrejme inú riadiacu premennú:
Výsledok:
N-rozmerné polia
Niekedy môže byť vhodné vytvoriť si pole o ešte viacerých dimenziách. My všetci si určite dokážeme predstaviť minimálne 3D poľa. S príkladom s kinosálou sa ponúka prípad použitia, keď má budova viac poschodí (alebo všeobecne viac kinosál). Vizualizácia by vyzerala asi nejako takto:
3D pole môžeme vytvoriť tým istým spôsobom, ako 2D pole:
Kód vyššie vytvorí 3D pole ako na obrázku. Pristupovať k nemu budeme opäť cez indexery (hranaté zátvorky) ako predtým, len už musíme zadať 3 súradnice.
Ak sa spýtame na
kinosaly[0][0].length
, získame počet „poschodí“
(kinosálov).
Zubaté polia
Pre všetky stĺpce nemusíme udávať tú istú dĺžku. Výsledkom je potom pole "zubaté" (v anglickej literatúre ako "jagged array"). Výhodou deklarovania 2D polí týmto spôsobom je, že do každého riadku/stĺpca môžeme potom uložiť aké veľké pole chceme. Týmto spôsobom môžeme ušetriť pamäť.
Takéto 2D pole deklarujeme nasledujúcim spôsobom:
A môžeme si ho predstaviť takto:
Nevýhodou tohto prístupu je, že musíme pole nepríjemne inicializovať sami. Pôvodný riadok s piatimi bunkami síce existuje, ale jednotlivé stĺpčeky si do neho musíme navkladať sami (zatiaľ si vložme všetky stĺpčeky s 5timi prvkami):
Java tiež ďalej neposkytuje žiadny komfort vo forme získania počtu stĺpcov a riadkov polí polí. Veľkosť poľa musíme získať takto:
Všimnite si, že je nutné
pýtať sa na počet stĺpcov, pokiaľ je totiž 0
, nemôžeme sa
dostať k 1. stĺpcu, aby sme zistili jeho dĺžku (počet riadkov v
stĺpci).
K hodnotám v poli potom pristupujeme pomocou 2 indexerov:
Skrátená inicializácia viacrozmerných polí
Ešte si ukážeme, že aj viacrozmerné polia je možné rovno inicializovať hodnotami (kód vytvorí rovno zaplnený kinosál ako na obrázku):
(Pole je v tomto zápise otočené, pretože definujeme stĺpce, ktoré tu zapisujeme ako riadky).
Podobnú inicializáciu môžeme použiť dokonca aj pri poliach zubatých (kód nižšie vytvorí zubaté pole ako na obrázku):
Na záver by som rád dodal,
že niektorí ľudia, ktorí nevedia správne používať objekty, využívajú
2D polí na ukladanie viacerých údajov o jedinej entite. Napr. budeme chcieť
uložiť výšku, šírku a dĺžku piatich mobilných telefónov. Hoci sa vám
teraz môže zdať, že sa jedná o úlohu na 3D pole, v skutočnosti sa jedná
o úlohu na obyčajné 1D pole (presnejšie zoznam) objektov typu
Telefon
. Ale o tom až pri objektovo orientovanom programovaní.
Pole si môžete vyskúšať ešte v cvičení v tejto sekcii.