Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Vícerozměrná pole v Javě

Dnešní tutoriál je v kurzu základních konstrukcí Javy v podstatě bonusový a pojednává o tzv. vícerozměrných polích. Teoreticky můžete rovnou přejít k objektově orientovanému programování, doporučuji však si konec této sekce ještě alespoň projít, abyste měli o zbývajících technikách povědomí, přeci jen se jedná o dosti základní vědomosti.

Již umíme pracovat s jednorozměrným polem, které si můžeme představit jako řádku přihrádek v paměti počítače.

Struktura pole v Javě - Kolekce a proudy v Javě

(Na obrázku je vidět pole osmi čísel)

Ačkoli to není tak časté, v programování se občas setkáváme i s vícerozměrnými poli a to zejména pokud programujeme nějakou simulaci (např. hru).

Dvourozměrné pole

Dvourozměrné pole si můžeme v paměti představit jako tabulku a mohli bychom takto reprezentovat např. rozehranou partii piškvorek. Pokud bychom se chtěli držet reálných aplikací, které budete později v zaměstnání tvořit, můžeme si představit, že do 2D pole budeme ukládat informace o obsazenostech sedadel v kinosálu. Situaci bychom si mohli graficky znázornit např. takto:

Struktura dvourozměrného pole v Javě - Kolekce a proudy v Javě

(Na obrázku je vidět 2d pole reprezentující obsazenost kinosálu)

Kinosál by byl v praxi samozřejmě větší, ale jako ukázka nám toto pole postačí. 0 znamená volno, 1 obsazeno. Později bychom mohli doplnit i 2 - rezervováno a podobně. Pro tyto stavy by bylo správnější vytvořit si vlastní datový typ, tzv. výčet, ale s ním se setkáme až později, takže si teď musíme vystačit pouze s čísly.

Java ve skutečnosti neposkytuje žádnou dodatečnou podporu pro vícerozměrná pole, můžeme si je však jednoduše deklarovat jako pole polí. Definice takového pole pro kinosál by vypadala takto:

int[][] kinosal = new int[5][5];

První číslice udává počet sloupců, druhá počet řádků (samozřejmě si to můžeme určit i obráceně, např. matice v matematice se zapisují opačně).

Všechna číselná pole v Javě jsou po deklaraci automaticky inicializována samými nulami, můžeme se na to spolehnout. Vytvořili jsme si tedy v paměti tabulku plnou nul.

Naplnění daty

Nyní kinosál naplníme jedničkami tak, jak je vidět na obrázku výše. Protože budeme jako správní programátoři líní, využijeme k vytvoření řádku jedniček for cykly :) Pro přístup k prvku 2D pole musíme samozřejmě zadat 2 souřadnice.

kinosal[2][2] = 1; // Prostředek
for (int i = 1; i < 4; i++) // 4. řádek
{
    kinosal[i][3] = 1;
}
for (int i = 0; i < 5; i++) // Poslední řádek
{
    kinosal[i][4] = 1;
}

Výpis

Výpis pole opět provedeme pomocí cyklu, na 2d pole budeme potřebovat cykly 2 (jeden nám proiteruje sloupce a druhý řádky). Jako správní programátoři nevložíme počet řádků a sloupců do cyklů napevno, jelikož se může změnit.

Musíme však pamatovat na skutečnost, že když se zeptáme na kinosal.length, bude obsahovat počet sloupců (přesněji délku vnějšího pole, které představuje sloupce). Abychom získali počet řádků (délku vnitřního pole, které sloupec reprezentuje), zeptáme se na kinosal[0].length. Všimněte si, že na to v poli musí být tedy alespoň jeden řádek.

Cykly zanoříme do sebe tak, aby nám vnější cyklus projížděl řádky a vnitřní sloupce v aktuálním řádku. Po výpisu řádku je nutné odřádkovat. Oba cykly musí mít samozřejmě jinou řídící proměnnou:

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

Výsledek:

Konzolová aplikace
00000
00000
00100
01110
11111

N-rozměrná pole

Někdy může být příhodné vytvořit si pole o ještě více dimenzích. My všichni si jistě dokážeme představit minimálně 3D pole. S příkladem s kinosálem se nabízí případ užití, kdy má budova více pater (nebo obecně více kinosálů). Vizualizace by vypadala asi nějak takto:

3D pole v Javě - Kolekce a proudy v Javě

3D pole můžeme vytvořit tím samým způsobem, jako 2D pole:

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

Kód výše vytvoří 3D pole jako na obrázku. Přistupovat k němu budeme opět přes indexery (hranaté závorky) jako předtím, jen již musíme zadat 3 souřadnice.

kinosaly[3][2][1] = 1; // Druhý kinosál, třetí řada, čtvrtý sloupec

Pokud se zeptáme na kinosaly[0][0].length, získáme počet "pater" (kinosálů).

Zubatá pole

Pro všechny sloupce nemusíme udávat tu samou délku. Výsledkem je potom pole "zubaté" (v anglické literatuře jako "jagged array"). Výhodou deklarování 2D polí tímto způsobem je, že do každého řádku/sloupce můžeme poté uložit jak velké pole chceme. Tímto způsobem můžeme ušetřit paměť.

Takové 2D pole deklarujeme následujícím způsobem:

int[][] kinosal = new int[5][];

A můžeme si jej představit takto:

Pole polí v Javě - Kolekce a proudy v Javě

Nevýhodou tohoto přístupu je, že musíme pole nepříjemně inicializovat sami. Původní řádek s pěti buňkami sice existuje, ale jednotlivé sloupečky si do něj musíme navkládat sami (zatím si vložme všechny sloupečky o 5ti prvcích):

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

Java rovněž dále neposkytuje žádný komfort ve formě získání počtu sloupců a řádků polí polí. Velikost pole musíme získat takto:

int sloupcu = kinosal.length;
int radku = 0;
if (sloupcu != 0)
    radku = kinosal[0].length;

Všimněte si, že je nutné ptát se na počet sloupců, pokud je totiž 0, nemůžeme se dostat k 1. sloupci, abychom zjistili jeho délku (počet řádků ve sloupci).

K hodnotám v poli poté přistupujeme pomocí 2 indexerů:

kinosal[4][2] = 1; // Obsazujeme sedadlo v 5. sloupci a 3. řadě

Zkrácená inicializace vícerozměrných polí

Ještě si ukážeme, že i vícerozměrná pole je možné rovnou inicializovat hodnotami (kód vytvoří rovnou zaplněný kinosál jako na obrázku):

int[][] kinosal = {
    { 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ápisu otočené, jelikož definujeme sloupce, které zde zapisujeme jako řádky).

Podobnou inicializaci můžeme použít dokonce i u polí zubatých (kód níže vytvoří zubaté pole jako na obrázku):

int[][] zubatePole = {
    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ávěr bych rád dodal, že někteří lidé, kteří neumí správně používat objekty, využívají 2D polí k ukládání více údajů o jediné entitě. Např. budeme chtít uložit výšku, šířku a délku pěti mobilních telefonů. Ačkoli se vám nyní může zdát, že se jedná o úlohu na 3D pole, ve skutečnosti se jedná o úlohu na obyčejné 1D pole (přesněji seznam) objektů typu Telefon. Ale o tom až u objektově orientovaného programování. Pole si můžete vyzkoušet ještě v cvičení v této sekci.

V následujícím cvičení, Řešené úlohy k 1.-5. lekci práce s kolekcemi v Javě, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Předchozí článek
Kvíz - Genericita, seznam a spojový seznam v Javě
Všechny články v sekci
Kolekce a proudy v Javě
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 1.-5. lekci práce s kolekcemi v Javě
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
381 hlasů
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 se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity