14 KiB
14 KiB
Pole
- Strukturovaný datový typ pro uložení více prvků stejného typu
- Pro uložení více hodnot stejného typu se hodí pole
Základní práce s (jednorozměrným) polem
- Pole
- Strukturovaný datový typ
- Skládá se z pevně daného počtu prvků
- Je homogenní – všechny prvky v něm uložené jsou stejného typu
- Počet prvků se stanoví při inicializaci (vytvoření) pole a pak již nelze změnit
- Počet prvků je délka pole, která je v poli kromě prvků rovněž uložená
- Indexy
- Jednotlivé prvky pole jsou přístupné pomocí indexů
- V Javě má index vždy hodnoty 0 až délka pole - 1
Deklarace a vytvoření pole
- Pole je podobné třídám a objektům
- V podstatě se jedná o speciální třídu a při inicializaci pole vytváříme její „instanci“ uloženou na haldě
- Je potřeba deklarovat referenční proměnou a vytvořit novou „instanci pole“ operátorem
new
- Stejně jako u objektů je možné udělat obojí najednou, nebo nejprve deklarovat referenční proměnou a později vytvořit nové pole
datovýTyp[] proměnná = new datovýTyp[početPrvků];
- Při vytváření nového pole se udává počet prvků (v hranatých závorkách „[“ a „]“), které bude pole obsahovat
- Typ prvků pole může být libovolný
- Libovolný základní datový typ
- Libovolná třída
- Protože proměnná typu pole je referenční, může být
null
- Pokud se jedná o lokální proměnnou a nevytváříme pole hned při deklaraci jeho referenční proměnné, je rozumné inicializovat referenční proměnnou na
null
- Pokud se jedná o proměnnou instance nebo třídy, je inicializována na
null
implicitně
- Pokud se jedná o lokální proměnnou a nevytváříme pole hned při deklaraci jeho referenční proměnné, je rozumné inicializovat referenční proměnnou na
- Při vytvoření pole jsou jeho jednotlivé prvky implicitně inicializovány na
0, 0.0, false
nebonull
podle datového typu pole- I v případě, že referenční proměnná ukazující na pole je lokální
- Vytvoření pole výčtem hodnot
- Pole je kromě operátoru
new
možné vytvořit i výčtem jeho hodnot uvedeným ve složených závorkách„{“
a„}“
- Např.
int[] fibonacci = {0, 1, 1, 2, 3, 5, 8, 13};
- Pole má stejné vlastnosti jako pole vytvořené operátorem
new
– délku pole určí překladač podle počtu prvků - Často používáno jako vzorová data pro usnadnění ladění, nebo uložení pole konstantních hodnot
- POZOR! – Takto definované pole nemá konstantní prvky, jeho prvky lze libovolně měnit, např.
fibonacci[3] = -6;
- POZOR!
- Samotným výčtem hodnot lze pole vytvořit POUZE PŘI DEKLARACI
- Pokud chceme přiřadit do existující referenční proměnné nové pole výčtem hodnot, musí samotnému výčtu předcházet vytvoření pole operátorem
new
bez udání počtu prvků - proměnná =
new datovýTyp[] {hodn1, hodn2, …};
- Např.
fibonacci = new int[] {1, 1, 2, 3};
- Pole je kromě operátoru
- Konstantní pole
- Použití klíčového slova
final
nezajistí, aby prvky pole po prvním přiřazení nešly změnit final
pouze zajistí konstantnost referenční proměnné – nelze do ní již přiřadit jinou hodnotu (tj. jiné pole)- Prvky pole, na které ukazuje
final
referenční proměnná lze ale měnit bez problémů - To samé platí pro referenční proměnné a instance tříd – hodnoty atributů (proměnných) instance lze měnit, i když je referenční proměnná ukazující na instanci označena jako
final
- Prvky pole, na které ukazuje
- Použití klíčového slova
Přístup k prvkům pole a jeho délka
- K jednotlivým prvkům pole se přistupuje pomocí indexu
- Index se zapisuje za referenční proměnou do hranatých závorek
proměnná[index]
- Prvek pole se chová stejně jako proměnná odpovídajícího datového typu
- Lze do něj zapisovat hodnotu
- Lze z něj číst hodnotu
- Např.
teploty[0] = 17.5;
- Např.
double teplota = teploty[0];
- Délka pole
- Každé pole má v sobě informaci o délce uloženou v proměnné
length
- Volá se přes tečkovou notaci stejně jako proměnná instance nad referenční proměnnou pole
- Např.
int pocetTeplot = teploty.length;
- První prvek pole má index 0
Např. double prvniTeplota = teploty[0];
- Poslední prvek pole má index
pole.length – 1
- Např.
double posledniTeplota = teploty[teploty.length - 1];
- Např.
- Index mimo rozsah pole
- POZOR! – Při pokusu o přístup k prvkům se záporným indexem nebo indexem větším nebo rovným délce pole, dojde k chybě za běhu programu (nikoliv při překladu) – je vyhozena výjimka
ArrayIndexOutOfBoundsException
- POZOR! – Při pokusu o přístup k prvkům se záporným indexem nebo indexem větším nebo rovným délce pole, dojde k chybě za běhu programu (nikoliv při překladu) – je vyhozena výjimka
- Každé pole má v sobě informaci o délce uloženou v proměnné
- Použití pole jako parametr metody
- Pole může být použito jako parametr metody (stejně jako primitivní datový typ nebo třída)
- POZOR! – Stejně jako u tříd a instancí platí, že změny provedené v hodnotách pole předaného do metody jako parametr se projeví vně metody
Výpis celého pole, inicializace stejnou hodnotou
- Pro práci s poli existuje utility třída
java.util.Arrays
- Obsahuje statické metody (podobně jako třída
Math
) pro práci s poli
- Obsahuje statické metody (podobně jako třída
- Výpis celého pole
- Metoda
Arrays.toString()
- Převede celé pole na řetězec, který lze následně vypsat např. metodou
System.out.println();
- POZOR!
- Sama metoda řetězec pouze vrací, nevypisuje ho
- Podobně jako metoda instance toString() u objektů
- Převede celé pole na řetězec, který lze následně vypsat např. metodou
- Pokud necháme vypsat pole metodou
System.out.println()
přímo (bez metodyArrays.toString()
), vypíše se pouze identifikace „instance pole“- Podobně jako implicitní implementace metody instance
toString()
u objektů - Např. volání
System.out.println(vektor1);
vypíše např. [D@1b6d3586 (čísla za „@“ se budou při různých spuštěních lišit)
- Podobně jako implicitní implementace metody instance
- Metoda
- Inicializace prvků pole stejnou hodnotou
- Prvky pole jsou při vytvoření implicitně inicializovány na
0, 0.0, false
nebonull
podle datového typu pole - Pokud je potřeba inicializovat pole jinou hodnotou (stejnou pro všechny prvky), je možné využít metodu
Arrays.fill(pole, hodnota);
- Např.
Arrays.fill(ciselnaRada, 1);
naplní všechny prvky poleciselnaRada
hodnotou1
- Metoda je překrytá pro pole všech základních datových typů a pole typu
Object
- Metoda je překrytá pro pole všech základních datových typů a pole typu
- Např.
- Existuje i varianta s určením počátečního a koncového indexu vyplnění pole
Arrays.fill(pole, indexOd, indexDo, hodnota);
Např.Arrays.fill(ciselnaRada, 0, 2, 10);
naplní první dva prvky (počáteční index je včetně, koncový není včetně) poleciselnaRada
hodnotou10
- Prvky pole jsou při vytvoření implicitně inicializovány na
Použití zápisu for - each
- Pokud nepotřebujeme pracovat s indexem pole a stačí nám postupný přístup ke všem jednotlivým prvkům, je možné použít zkrácený zápis cyklu
for
(známý též jakofor - each
)for (datovýTyp prvek: pole)
- Cyklus zaručí, že se dostane na všechny prvky – projde se celé pole od začátku do konce
- V každé obrátce cyklu je v proměnné prvek následující prvek pole
- Běžně se používá pro pole (a kolekce – viz předmět KIV/PPA2) objektů
Pole jako tabulka, přepočet indexů
- Tabulka
- Datová struktura obsahující dvojice klíč a hodnota
- Pro daný klíč můžeme získat hodnotu
- Viz předměty KIV/PPA2 a KIV/PT
- Pole se dá použít jako jednoduchá tabulka
- Index může sloužit jako klíč
- Hodnota prvku pole jako hodnota
- Indexy pole začínají vždy od 0 – pokud je potřeba jiný začátek klíčů, je potřeba přepočet
Reprezentace množiny polem
- Množina
- Soubor prvků (např. čísel) chápaných jako celek
- Každý prvek může být obsažen v množině maximálně jednou
- Pro reprezentaci množiny lze využít pole typu
boolean[]
- Indexy odpovídají prvkům množiny
- Hodnoty prvků pole udávají, zda prvek je přítomný v množině (
true
) nebo není (false
)
Pole objektů
- Prvkem pole můžou být kromě základních datových typů i instance
- Použití se nijak neliší, jen je potřeba nezapomenout vytvořit instance jednotlivých prvků, což se u základních datových typů nedělá
Deklarace pole objektů a jeho inicializace
- Deklarace a vytvoření pole se neliší od polí základních datových typů
- Je potřeba deklarovat referenční proměnnou a vytvořit novou „instanci pole“ operátorem
new
Třída[] proměnná = new Třída[početPrvků];
- Např.
Vysledek[] vysledky = new Vysledek[POCET];
- Opět je možné nejprve deklarovat referenční proměnnou a později vytvořit nové pole
- Jednotlivé prvky referenční proměnné na instance třídy odpovídající typu pole
- Po vytvoření pole jsou všechny implicitně inicializovány na hodnotu
null
- POZOR! – V tomto okamžiku (po vytvoření pole) tedy jednotlivé instance prvků neexistují – dosud nebyly vytvořeny operátorem
new
- Po vytvoření pole jsou všechny implicitně inicializovány na hodnotu
- Je potřeba deklarovat referenční proměnnou a vytvořit novou „instanci pole“ operátorem
- Vytvoření instancí prvků pole
- Instanci každého prvku je potřeba vytvořit zvlášť, typicky v cyklu
for
- Instanci každého prvku je potřeba vytvořit zvlášť, typicky v cyklu
Přístup k prvkům pole a k proměnným a metodám instance prvků
- Přístup k prvkům pole je stejný jako u polí základních datových typů pomocí indexu v hranatých závorkách „[“ a „]“
- Jednotlivé prvky jsou referenční proměnné ukazující na jednotlivé instance
- Přístup k atributům a metodám instance je přes tečkovou notaci použitou nad prvkem pole
Vícerozměrná pole
- Pole může mít více rozměrů
- Často se využívají dvourozměrná (např. pro uložení matic), ale mohou být i tří a vícerozměrná
- Pole s více než třemi rozměry většinou nemají reálné opodstatnění
- Pro určení požadovaného prvku pole je potřeba více indexů
- Počet odpovídá počtu rozměrů pole
- Vícerozměrné pole jako pole polí
- Dvourozměrné pole v Javě je ve skutečnosti jednorozměrné pole referenčních proměnných, kde každá ukazuje na jednorozměrná pole (tj. „řádku“)
- Díky tomu má každé jednorozměrné pole svou délku, kterou je možné zjistit, a dvourozměrné pole ji má též
- Z dvourozměrného pole tak lze zjistit jeho počet řádek i sloupců
- Každé jednorozměrné pole může mít jinou délku
- Trojrozměrné pole v Javě je pak jednorozměrné pole referenčních proměnných, kde každá ukazuje na dvourozměrné pole, atd.
- Dvourozměrné pole v Javě je ve skutečnosti jednorozměrné pole referenčních proměnných, kde každá ukazuje na jednorozměrná pole (tj. „řádku“)
Deklarace a vytvoření vícerozměrného pole
- Deklarace referenční proměnné pro vícerozměrné pole je podobná jako pro jednorozměrné
- Pouze obsahuje více prázdných párů hranatých závorek „[]“ – jeden pár pro každý rozměr pole
datovýTyp[][]…[] proměnná;
Např.double[][] prvkyMatice;
- Vytvoření všech rozměrů najednou
- Nejběžnější použití vícerozměrných polí
- Počty prvků ve všech rozměrech pole udány najednou
- V případě dvourozměrného pole má každý řádek stejnou šířku
- Tzv. pravoúhlé pole – pole tvoří pravoúhlý obrazec – obdélník, kvádr, teserakt, atd.
proměnná = new datovýTyp[počet1][počet2]…[početN];
- Např.
prvkyMatice = new double[vyska][sirka];
- Vytvoření rozměrů postupně
- Počty prvků v jednotlivých rozměrech udány postupně
- Nejprve vytvoříme „vnější“ pole a pak do jeho jednotlivých prvků přiřadíme nové „instance“ „vnitřních“ polí
- V případě dvourozměrného pole může mít každý řádek různou délku
- Pole je „zubaté“
proměnná = new datovýTyp[počet1][]…[];
- POZOR!
- Musí se vždy začínat rozměrem nejvíc vně (tj. první závorky zleva)
- Nelze
proměnná = new datovýTyp[][počet2]…[];
- Vytvoření pole výčtem hodnot
- I vícerozměrné pole je možné vytvořit výčtem hodnot
- Pole může být pravoúhlé i „zubaté“
- Platí stejná pravidla, jako při vytváření jednorozměrného pole
- Použití samotného výčtu je možné pouze při deklaraci, při pozdějším vytvoření pole je nutné použít i operátor
new
- Použití samotného výčtu je možné pouze při deklaraci, při pozdějším vytvoření pole je nutné použít i operátor
- I vícerozměrné pole je možné vytvořit výčtem hodnot
Přístup k prvkům pole
- Pro přístup k jednotlivým prvkům vícerozměrného pole se používá více indexů
- Počet indexů odpovídá počtu rozměrů pole
- Použití méně indexů než je rozměrů pole
- Při použití méně indexů se nedostaneme k prvku pole, ale k poli s menším rozměrem
- Např. pokud máme dvourozměrné pole a použijeme pouze jeden index, dostaneme se k jednorozměrnému („vnitřnímu“) poli, tj. k „řádce“ pole
- V okamžiku, kdy se dostaneme na „vnitřní“ pole, můžeme zjistit jeho délku
- To se velmi často využívá
- Funguje dobře při procházení vícerozměrného pole, i pokud je pole „zubaté“
Pole v paměti
- Pole je ve skutečnosti instance speciální třídy a je celé uloženo na haldě (heap)
- Jak to vypadá v paměti při práci s poli, je demonstrováno na příkladu s polem primitivního datového typu a na příkladu s polem objektů
- Pole nulové délky
- Pole může mít délku 0 prvků
- Pak nemá žádný prvek, do kterého by šla zapsat hodnota, ale může být použitelná informace o nulové délce
- Rozdíl oproti referenční proměnné pole rovné
null
- Referenční proměnná pole rovná null neukazuje na žádné pole (žádné pole není na haldě)
- Pole nulové délky na haldě existuje a ukazuje na něj referenční proměnná, neobsahuje ale žádný prvek
Pole primitivních datových typů v paměti
- Pole primitivních datových typů ve své „instanci“ přímo obsahuje hodnoty jednotlivých prvků