Vianoce v ITnetwork sú tu! Dobí si teraz kredity a získaj až 80 % extra kreditov na e-learningové kurzy ZADARMO. Zisti viac.
Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.

5. diel - Viacrozmerné polia v Jave

V predchádzajúcom kvíze, Kvíz – Genericita, zoznam a spojový zoznam v Jave, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.

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 je možné rovno prejsť k objektovo orientovanému programovaniu, ore získanie povedomia o zvyšných technikách však odporúčame si koniec tejto sekcie ešte aspoň prejsť, 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.

Štruktúra poľa v Jave - Kolekcie a prúdy v Jave

(Na obrázku je vidno 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é budeme 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:

Štruktúra dvojrozmerného poľa v Jave - Kolekcie a prúdy v Jave

(Na obrázku je vidno 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. výpočtový typ, 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álu by vyzerala takto:

int[][] cinema = new int[5][5];

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 vidno 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ť dve súradnice:

cinema[2][2] = 1; // The middle part
for (int i = 1; i < 4; i++) { // The 4th row
    cinema[i][3] = 1;
}
for (int i = 0; i < 5; i++) { // The last row
    cinema[i][4] = 1;
}

Výpis

Výpis poľa opäť vykonáme pomocou cyklu, na 2D pole budeme potrebovať dva cykly (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 ich počet môže zmeniť.

Musíme však pamätať na skutočnosť, že keď sa spýtame na cinema.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 cinema[0].length. Všimneme 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ú:

for (int j = 0; j < cinema[0].length; j++) {
    for (int i = 0; i < cinema.length; i++) {
        System.out.print(cinema[i][j]);
    }
    System.out.println();
}

Výsledok:

Konzolová aplikácia
00000
00000
00100
01110
11111

N-rozmerné pole

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 pole. 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 v Jave - Kolekcie a prúdy v Jave

3D pole môžeme vytvoriť tým istým spôsobom ako 2D pole:

int[][][] cinemas = new int [4][4][3];

Kód vyššie vytvorí 3D pole ako na obrázku. Pristupovať k nemu budeme opäť cez indexery (hranaté zátvorky), len už musíme zadať tri súradnice.

cinemas[3][2][1] = 1; // The second cinama, third row, fourth seat.

Ak sa spýtame na cinemas[0][0].length, získame počet "poschodí" (kinosálov).

Zubaté pole

Pre všetky stĺpce nemusíme udávať tú istú dĺžku. Výsledkom je potom pole "zubaté" (v angličtine "jagged array"). Výhodou deklarovania 2D polí týmto spôsobom je, že do každého riadku/stĺpca môžeme potom vložiť, aké veľké pole chceme. Týmto spôsobom môžeme ušetriť pamäť.

Takéto 2D pole deklarujeme nasledujúcim spôsobom:

int[][] cinema = new int[5][];

A môžeme si ho predstaviť takto:

Zubaté pole v Jave - Kolekcie a prúdy v Jave

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 vložiť sami (zatiaľ si vložme všetky stĺpčeky s piatimi prvkami):

for (int i = 0; i < cinema.length; i++) {
    cinema[i] = new int[5];
}

Java taktiež ď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:

int columns = cinema.length;
int rows = 0;
if (columns != 0) {
    rows = cinema[0].length;
}

Všimneme 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 dvoch indexerov:

cinema[4][2] = 1; // The seat in the 5th column and the 3rd row

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álu ako na obrázku):

int[][] cinema = {
    { 0, 0, 0, 0, 1 },
    { 0, 0, 0, 1, 1 },
    { 0, 0, 1, 1, 1 },
    { 0, 0, 0, 1, 1 },
    { 0, 0, 0, 0, 1 }
};

(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):

int[][] jaggedArray = {
    new int[] {15, 2, 8, 5, 3},
    new int[] {3, 3, 7},
    new int[] {9, 1, 16, 13},
    new int[] {},
    new int[] {5}
};

Na záver by by sme radi dodali, ž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 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ôžeme vyskúšať ešte v cvičení v tejto sekcii.

V nasledujúcom cvičení, Riešené úlohy k 1.-5. lekcii práce s kolekciami v Jave, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Predchádzajúci článok
Kvíz – Genericita, zoznam a spojový zoznam v Jave
Všetky články v sekcii
Kolekcie a prúdy v Jave
Preskočiť článok
(neodporúčame)
Riešené úlohy k 1.-5. lekcii práce s kolekciami v Jave
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
22 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity