<< "Inicializačné metódy" (konštruktory) | Obsah | Dvojrozmerné polia >>
Doposiaľ vždy, keď sme chceli pracovať s nejakým objektom, musela existovať premenná, ktorá tento objekt referencovala. Problém však vzniká v prípade, že potrebujeme pracovať s veľmi veľa objektami (napr. 100 korytnačiek). Je jasné, že vytvorene 100 premenných referencujúcich objekty triedy Turtle
nie je práve ideálne riešenie. Analogicky, ak chceme realizovať nejaký výpočet, hodnoty uchovávame v premenných. Avšak, ak je dát veľa, použitie jednoduchých premenných (či už lokálnych alebo inštančných) neprichádza do úvahy. Riešením vyššie spomenutých problémov sú polia.
Polia sú špeciálne Java objekty, ktoré nám umožňujú uchovať veľa premenných rovnakého typu "pod jednou strechou". Každý "poľový" objekt sa skladá z dopredu určeného počtu políčok. Jednotlivé políčka sú usporiadané za sebou a očíslované. Číslovanie (indexovanie), tak ako to býva v Jave zvykom, začína od čísla 0. Každé políčko funguje ako samostatná premenná, t.j. uchováva hodnotu alebo referenciu v závislosti od typu políčok poľa.
Deklarácia premennej referencujúcej pole. Keďže polia sú objekty, na to, aby sme s nimi mohli aktívne pracovať, potrebujeme premennú referenčného typu, ktorá by referencovala "poľové" objekty. Premennú, ktorá referencuje polia ("poľové objekty") s políčkami typy Typ
, deklarujeme takto:
Za Typ
môžeme dosadiť ľubovoľný doposiaľ používaný typ premennej:
Vo vyššie uvedenom príklade premenná poleReferenciiNaKorytnacky
je premennou referenčného typu, ktorá je schopná referencovať polia ("poľové" objekty), ktorých políčka sú typu Turtle
- to jest, každé políčko referencovaného poľa uchováva referenciu ("rodné číslo") na nejaký objekt triedy Turtle
. Premenná poleCisel
v tomto príklade je schopná referencovať pole ("poľový" objekt), ktorého každé políčko uchováva nejaké celé číslo (hodnotu typu int
).
Vytvorenie poľa. Povedzme si ešte, ako pole ("poľový" objekt) vytvoríme. Ak chceme vytvoriť pole, ktoré bude mať n
políčok typu TypPolicka
, tak použijeme príkaz:
V nasledujúcom príklade sa najprv vytvorí premenná korytnacky
, ktorá je schopná referencovať polia s políčkami typu Turtle
. Následne sa príkazom new
vytvorí pole ("poľový" objekt), ktorý bude mať 10 políčok. Každé z týchto políčok bude schopné uchovávať referenciu na nejaký objekt triedy Turtle
. Nakoniec sa referencia na vytvorené pole (objekt) uloží do premennej korytnacky
:
Políčka vytvoreného poľa fungujú ako klasické premenné. Aký je teda ich obsah po vytvorení poľa ? Pamätajme si, že políčka poľa sú automaticky inicializované "defaultnými" hodnotami (v závislosti od typu políčok), presne tak, ako je to u inštančných (objektových) premenných. V predchádzajúcom príklade budú políčka vytvoreného poľa inicializované hodnotami null
, keďže typ Turtle
je referenčným typom (políčka poľa sú referenčného typu).
Prístup k políčkam (prvkom) poľa. Po vytvorení poľa chceme prirodzenie s políčkami poľa pracovať. Na prístup ku konkrétnemu políčku poľa používame hranaté zátvorky []
, medzi ktoré pridáme index políčka (jeho poradové číslo):
Medzi []
môžeme napísať nielen konkrétnu hodnotu (celočíselný literál), ale aj ľubovoľný aritmetický výraz, ktorého výsledkom je celé číslo. Toto číslo sa použije ako index na prístup ku konkrétnemu políčku poľa. Keďže polia sú objekty, uvedomme si, že zápis korytnacky[3]
v skutočnosti znamená: políčko na indexe 3 (4. políčko) poľa referencovaného z premennej korytnacky
. (Pre lepšiu ilustráciu viď slidy k prednáške.)
Ilustračný obrázok podľa http://java.sun.com/docs/books/tutorial/java/nutsandbolts/arrays.html
Počet prvkov (políčok) poľa. Spomeňme si, že v prípade reťazcov (objektov triedy String
) sme vedeli počet znakov v reťazci zistiť pomocou metódy length()
. V prípade polí, ale niečo také nefunguje. Namiesto volania metódy nám Java ponúka špeciálnu konštrukciu .length (pozor, nie je to metóda a preto žiadne okrúhle zátvorky), pomocou ktorej vieme zistiť počet prvkov poľa.
Nasledujúci príklad spočíta, v koľkých políčkach je uložená hodnota null
:
Pamätajme si tiež, že počet políčok poľa (hovoríme aj dĺžku poľa) po jeho vytvorení už nemôžeme zmeniť.
null
. Inými slovami, žiadne políčko neobsahuje ako svoju hodnotu "rodné číslo" objektu. Ak chceme mať v poli referencie na konkrétne objekty, musíme ich najprv vytvoriť resp. referencie na ne odniekiaľ získať. To je zrejmé, pretože ak je políčko poľa referenčného typu, obsahuje len referenciu ("rodné číslo") na nejaký objekt. Ak však je políčko poľa primitívneho typu (int
, double
, ...) obsahuje políčko poľa priamo hodnotu. "Defaultné" hodnoty pre tieto typy možno nájsť v prechádzajúcej prednáške. Pripomeňme, že po vytvorení poľa (cez new
) sú v tomto prípade jednotlivé políčka poľa vyplnené touto "defaultnou" hodnotou.
Fragment programu zachycujúci prácu s poľom - vytvorenie a naplnenie poľa celých čísel:
V niektorých situáciach by sa celkom hodilo, keby vytvorené pole bolo rovno aj inicializované nejakými (pre naše potreby) rozumnými hodnotami (nie "defaultnými"). Java samozrejme aj na tento problém ponúka riešenie:
Tento zápis je totožný s týmito riadkami zdrojového kódu:
Ako môžeme vidieť, vytvorenie pola a nastavenie hodnôt pre políčka môžeme skombinovať do jedného príkazu. Za znak =
pridáme do kučeravých zátvoriek {}
čiarkami oddelenú postupnosť hodnôt pre jednotlivé políčka. Navyše v tomto zozname hodnôt okrem literálov môžeme uviesť aj (aritmetické alebo logické) výrazy.
Príklady:
Keďže práca s poľami je pri programovaní dosť častá, Java má už mnoho užitočných metód naprogramovaných (sú jej súčasťou).
Ak chceme vypísať obsah poľa zvyčajne použijeme for-cyklus, v ktorom vypíšeme prvky poľa "po jednom". Pomocou metódy Arrays.toString
vieme nechať si vyrobiť reťazec, ktorý bude obsahovať čiarkami oddelený zoznam hodnôt v poli.
Príklad:
Ďalšou častou činnosťou je kopírovanie obsahu políčok z jedného poľa do druhého poľa. Tu nám vie pomôcť metóda System.arraycopy
. Táto metóda má 5 parametrov, v poradí:
Pozrime sa na túto metódu v príklade:
Rôzne metódy (algoritmy) pracujúce s poľom sa môžu zdať na prvý pohľad veľmi zložité. V skutočnosti ide len o obmeny niekoľkých stratégii.
Typickým problémom, ktorý sa často rieši, je overenie toho, či všetky prvky poľa (hodnoty alebo objekty referencované z políčok poľa) majú nejakú vlastnosť. Príkladmi vlastností môžu byť tieto:
Základná stratégia na riešenie tohto problému je táto:
Túto stratégiu v Jave vieme vyjadriť nasledujúcim "pseudokódom". V ňom predpokladáme, že maVlastnost
je niečo, čo nám povie, či políčko poľa má alebo nemá (boolean
) skúmanú vlastnosť:
V prípade, že zisťovanie robíme v samostatnej metóde, môžeme použiť tento variant:
Pozrime sa, ako by vyzerala aplikovanie tejto stratégie v prípade, že chceme zistiť či všetky prvky majú hodnotu väčšiu alebo rovnú ako zadaná dolná hraničná hodnota hranica
:
Túto stratégiu vieme použiť dokonca aj v prípade, keď nás nezaujíma, či všetky prvky poľa majú nejakú vlastnosť, ale či všetky neusporiadané dvojice (alebo aj k-tice) rôznych prvkov majú nejakú vlastnosť:
Samozrejme, ak by to nebolo v samostatnej metóde, použijeme variant s break
-om a boolean
premennou.
Problém zistenia počtu prvkov poľa s nejakou vlastnosťou je veľmi podobný predchádzajúcemu problému. Na riešenie tohto problému využívame podobnú stratégiu. Namiesto boolean
premennej použijeme počítadlo, v ktorom si budeme počítať, koľko prvkov so skúmanou vlastnosťou sme stretli pri prechode prvkami poľa. Pozrime sa na "schému" riešiacu tento problém:
Pozrime sa na príklad metódy, ktorá spočíta, koľko korytnačiek je bližšie k zadanému bodu ako 100:
Analogicky tento mechanizmus vieme použiť aj na spočítanie počtu dvojíc (k-tíc), ktoré majú nejakú vlastnosť.
Ďalším častým riešeným problémom je nájdenie "naj" prvku poľa, resp. zistenie jeho hodnoty. Pod pojmom "naj" prvok poľa myslíme taký prvok poľa, ktorý je spomedzi všetkých prvkov poľa nejakým spôsobom najlepší. Pár príkladov najlepšieho prvku poľa:
Základná stratégia na riešenie tohto problému je táto (metafora: zápas):
V nasledujúcom predpokladajme, že jeLepsiAko(A, B)
nám povie, či A
je lepší ako B
(A > B
). Algoritmus na nájdenie najlepšieho prvku poľa môžeme v Jave vyjadriť takto:
Ilustrujme si túto schému na probléme nájdenia najväčšej hodnoty v poli:
Ilustrujme si tento mechanizmus ešte na nájdení korytnačky, ktorá má najmenšiu y-vú súradnicu:
Rovnako ako všetky skôr spomenuté "finty", aj táto úspešne funguje v prípade, kedy chceme nájsť nejakú najlepšiu dvojicu (alebo k-ticu) rôznych prvkov.
<< "Inicializačné metódy" (konštruktory) | Obsah | Dvojrozmerné polia >>