11. diel - Pole v Jave
V predchádzajúcom cvičení, Riešené úlohy k 9.-10. lekcii Javy, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnom Java tutoriále si predstavíme dátovú štruktúru poľa a vyskúšame si, čo všetko vie.
Pole
Predstavte si, že si chcete uložiť nejaké údaje o viacerých prvkoch.
Napríklad chcete v pamäti uchovávať 10 čísel, políčka šachovnice alebo
mená päťdesiatich používateľov. Asi vám dôjde, že v programovaní bude
existovať lepšia cesta než začať vymenovávať premenné
user1
, user2
, ... až user50
. Nehľadiac
na to, že ich môže byť trebárs aj 1000! A ako by sa v tom potom
vyhľadávalo? Brrr, takto nie
Ak potrebujeme uchovávať väčšie množstvo premenných rovnakého
typu, tento problém nám rieši pole. Môžeme si ho
predstaviť ako množstvo priehradiek, kde v každej máme uložený jeden
prvok. Priehradky sú očíslované tzv. indexmi, prvá má
index 0
:
(Na obrázku je vidieť pole ôsmich čísel.)
Programovacie jazyky sa veľmi líšia v tom, ako s poľom pracujú. V niektorých jazykoch (najmä starších, kompilovaných) nebolo možné za behu programu vytvoriť pole s dynamickou veľkosťou (napr. dať mu veľkosť podľa nejakej premennej). Pole sa muselo deklarovať s konštantnou veľkosťou priamo v zdrojovom kóde. Toto sa obchádzalo tzv. pointermi a vlastnými dátovými štruktúrami, čo často viedlo k chybám pri manuálnej správe pamäte a nestabilite programu (napr. v C++). Naopak niektoré interpretované jazyky umožňujú nielen deklarovať pole s ľubovoľnou veľkosťou, ale dokonca túto veľkosť na už existujúcom poli meniť (napr. PHP). My vieme, že Java je virtuálny stroj, teda niečo medzi kompilátorom a interpreterom. Preto môžeme pole založiť s veľkosťou, ktorú dynamicky zadáme až za behu programu, ale veľkosť existujúceho poľa modifikovať nemôžeme. Možno to samozrejme obísť alebo použiť iné dátové štruktúry, ale k tomu sa dostaneme.
Výhody poľa
Možno vám napadá, prečo sa tu zaoberáme poľom, keď má evidentne mnoho obmedzení a existujú lepšie dátové štruktúry. Odpoveď je jednoduchá: pole je totiž jednoduché. Nemyslím pre nás na pochopenie (to tiež), ale najmä pre Javu. Rýchlo sa s ním pracuje, pretože prvky sú v pamäti jednoducho uložené za sebou, všetky prvky zaberajú rovnako miesta a rýchlo sa k nim pristupuje. Veľa vnútorných funkčností preto v Jave s poľom nejako pracuje alebo ho vracia. Je to kľúčová štruktúra.
Na hromadnú manipuláciu s prvkami poľa sa používajú cykly.
Práca s poľom
V niekoľkých ďalších krokoch si pole deklarujeme, následne ho založíme a na záver naplníme vlastnými dátami.
Deklarácia poľa
Pole deklarujeme pomocou hranatých zátvoriek:
int[] numbers;
Slovo numbers
je samozrejme názov našej premennej. Teraz sme
však iba deklarovali, že v premennej bude pole prvkov typu int
.
Teraz ho musíme založiť, aby sme ho mohli používať. Pole pomenovávame
vždy množným číslom podľa toho, čo pole obsahuje.
Založenie poľa
Na založenie použijeme kľúčové slovo new
, ktoré zatiaľ
nebudeme vysvetľovať. Uspokojme sa s tým, že je to kvôli tomu, že pole je
referenčný dátový typ (môžeme chápať ako zložitejší typ):
int[] numbers = new int[10];
Teraz máme v premennej numbers
pole o veľkosti desiatich
čísel typu int
.
Prístup k prvkom poľa
K prvkom poľa potom pristupujeme cez hranatú zátvorku, poďme na prvý
index (teda index 0
) uložiť číslo 1
:
int[] numbers = new int[10]; numbers[0] = 1;
Naplnenie poľa cyklom
Plniť pole ručne dátami by bolo príliš pracné, použijeme
cyklus a naplníme si pole číslami od 1
do
10
. Na naplnenie použijeme cyklus for
:
int[] numbers = new int[10]; for (int i = 0; i < 10; i++) { numbers[i] = i + 1; }
Aby sme pole vypísali, môžeme za predchádzajúci kód pripísať:
{JAVA_CONSOLE}
int[] numbers = new int[10];
for (int i = 0; i < 10; i++) {
numbers[i] = i + 1;
}
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
{/JAVA_CONSOLE}
Všimnite si, že pole má konštantu length
, kde
je uložená jeho dĺžka, teda počet prvkov.
Výstup programu:
Konzolová aplikácia
1 2 3 4 5 6 7 8 9 10
Cyklus foreach
Môžeme použiť zjednodušenú verziu cyklu pre prácu s kolekciami známu ako tzv. foreach. Ten prejde všetky prvky v poli a jeho dĺžku si zistí sám. Jeho syntax je nasledovná:
for (datatype variable : collection) { // commands }
Cyklus prejde prvky v kolekcii (to je všeobecný názov pre štruktúry, ktoré obsahujú viac prvkov, u nás to bude pole) postupne od prvého do posledného. Prvok máme v každej iterácii cyklu uložený v danej premennej.
Prepíšme teda náš doterajší program pre cyklus foreach. Cyklus foreach nemá riadiacu premennú, nie je teda vhodný na vytvorenie nášho poľa a použijeme ho len na výpis:
{JAVA_CONSOLE}
int[] numbers = new int[10];
for (int i = 0; i < 10; i++) {
numbers[i] = i + 1;
}
for (int number : numbers) {
System.out.print(number + " ");
}
{/JAVA_CONSOLE}
Výstup programu:
Konzolová aplikácia
1 2 3 4 5 6 7 8 9 10
Naplnenie poľa ručne
Pole samozrejme môžeme naplniť ručne a to aj bez toho, aby sme dosadzovali postupne do každého indexu. Použijeme na to zložené zátvorky a prvky oddelíme čiarkou:
String[] simpsons = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
Polia často slúžia na ukladanie medzivýsledkov, ktoré sa potom ďalej v programe používajú. Keď niečo potrebujeme 10x, tak to nebudeme 10x počítať, ale spočítame to raz a uložíme do poľa, odkiaľ potom výsledok iba načítame.
Metódy na triede Arrays
Java nám poskytuje triedu Arrays
, ktorá obsahuje pomocné
metódy pre prácu s poľami.
Na jej použitie je potrebné ju naimportovať:
import java.util.Arrays;
Poďme sa na metódy pozrieť bližšie:
Metóda sort()
Ako už názov napovedá, metóda sort()
nám pole zoradí. Jej
jediný parameter je pole, ktoré chceme zoradiť. Metóda je dokonca taká
múdra, že pracuje podľa toho, čo máme v poli uložené. Reťazce triedi
podľa abecedy, čísla podľa veľkosti. Skúsme si zoradiť a vypísať našu
rodinku Simpsonovcov:
package onlineapp;
import java.util.Arrays;
public class Program {
public static void main(String[] args) {
String[] simpsons = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
Arrays.sort(simpsons);
for (String simpson: simpsons) {
System.out.print(simpson + " ");
}
}
}
Výstup programu:
Konzolová aplikácia
Bart Homer Lisa Maggie Marge
Skúste si urobiť pole čísel a vyskúšajte si, že to naozaj funguje aj pre ne.
Metóda binarySearch()
Keď pole zoradíme, Java nám v ňom umožní vyhľadávať prvky. Metóda
binarySearch()
nám vráti index prvého nájdeného prvku. V
prípade nenájdenia prvku vráti metóda hodnotu -1
. Metóda berie
dva parametre, prvým je pole a druhým hľadaný prvok. Umožníme
používateľovi zadať meno Simpsona a potom skontrolujeme, či je to naozaj
Simpson:
package onlineapp;
import java.util.Arrays;
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in, "Windows-1250");
String[] simpsons = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
System.out.println("Hello! Enter the name of a character in the Simpsons (you may only choose from the core family members): ");
String simpson = scanner.nextLine();
Arrays.sort(simpsons);
int position = Arrays.binarySearch(simpsons, simpson);
if (position >= 0)
System.out.println("Yes, it's a Simpson!");
else
System.out.println("Hey! That's not a Simpson!");
}
}
Pole musí byť naozaj zoradené, kým metódu zavoláme!
Výstup programu:
Konzolová aplikácia
Hello! Enter the name of a character in the Simpsons (you may only choose from the core family members):
Homer
Yes, it's a Simpson!
Metóda copyOfRange()
Metóda copyOfRange()
už podľa názvu skopíruje časť poľa
do iného poľa. Prvým parametrom je zdrojové pole, druhým štartovacia
pozícia a tretím konečná pozícia. Metóda vracia nové pole, ktoré je
výsekom pôvodného poľa.
Premenná dĺžka poľa
Hovorili sme si, že dĺžku poľa môžeme definovať aj za behu programu, poďme si to skúsiť:
Scanner scanner = new Scanner(System.in, "Windows-1250"); System.out.println("Hello, I'll calculate your grade average. How many grades would you like to enter?"); int count = Integer.parseInt(scanner.nextLine()); int[] grades = new int[count]; for (int i = 0; i < count; i++) { System.out.printf("Enter grade number %d: ", i + 1); grades[i] = Integer.parseInt(scanner.nextLine()); } // computing the average int sum = 0; for (int grade : grades) { sum += grade; } double average = sum / (double)grades.length; System.out.printf("Your grade average is: %.1f", average);
Príkaz sum += grade
je iba skrátený zápis pre
sum = sum + grade
.
Výstup programu:
Konzolová aplikácia
Hello, I'll calculate your grade average. How many grades would you like to enter?
5
Enter grade number 1: 1
Enter grade number 2: 2
Enter grade number 3: 2
Enter grade number 4: 3
Enter grade number 5: 5
Your grade average is: 2.6
Tento príklad by šiel samozrejme napísať aj bez použitia poľa, ale čo keby sme chceli spočítať napr. medián? Alebo vypísať zadané čísla pospiatky? To už by bez poľa nešlo. Takto máme k dispozícii v poli pôvodné hodnoty a môžeme s nimi neobmedzene a jednoducho pracovať.
Pri výpočte priemeru si všimnite, že pri delení je pred jedným
operandom napísané (double)
, tým hovoríme, že chceme deliť
neceločíselne. Pri delení 3 / 2
dostaneme výsledok
1
a pri delení 3 / 2.0F
dostaneme výsledok
1.5
. Druhé číslo musí byť vždy reálne, aby Java delila
taktiež reálne (na viac desatinných miest).
To by pre dnešok stačilo, môžete sa s poľom hrať.
V nasledujúcom kvíze, Kvíz - Podmienky, cykly a polia v Jave, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 15x (10.58 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java