NOVINKA: Získej 40 hodin praktických dovedností s AI – ZDARMA ke každému akreditovanému kurzu!
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 12 - Pole v Javě

V předešlém cvičení, Řešené úlohy k 10.-11. lekci Javy, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

V dnešním Java tutoriálu si představíme datovou strukturu pole a vyzkoušíme si, co všechno umí.

Pole

Představme si, že si chceme uložit nějaké údaje o více prvcích. Například chceme v paměti uchovávat 10 čísel, políčka šachovnice nebo jména padesáti uživatelů. Asi nám dojde, že v programování bude nějaká lepší cesta než začít bušit proměnné uzivatel1, uzivatel2 až např. uzivatel50. Nehledě na to, že jich může být třeba 1000! Jak by se pak navíc v takovém systému hledalo? Brrr, takto ne :)

Potřebujeme-li uchovávat větší množství proměnných stejného typu, tento problém nám řeší pole. Můžeme si ho představit jako řadu přihrádek, kdy v každé máme uložený jeden prvek. Přihrádky jsou očíslované tzv. indexy, přičemž první přihrádka má index 0:

Struktura pole - Základní konstrukce jazyka Java

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

Programovací jazyky se velmi liší v tom, jak s polem pracují. V některých jazycích (zejména starších, kompilovaných) nebylo možné za běhu programu vytvořit pole s dynamickou velikostí (např. mu dát velikost dle nějaké proměnné). Pole se muselo deklarovat s konstantní velikostí přímo ve zdrojovém kódu. Toto se obcházelo tzv. pointery a vlastními datovými strukturami, což často vedlo k chybám při manuální správě paměti a k nestabilitě programu (např. v C++). Naopak některé interpretované jazyky umožňují nejen deklarovat pole s libovolnou velikostí, ale dokonce tuto velikost na již existujícím poli měnit (např. PHP). My víme, že Java je virtuální stroj, tedy cosi mezi kompilerem a interpretem. Proto můžeme pole založit s velikostí, kterou dynamicky zadáme až za běhu programu, ale velikost existujícího pole již modifikovat nemůžeme. Toto lze samozřejmě obejít nebo použít jiné datové struktury, ale k tomu se dostaneme.

Výhody pole

Možná vás napadá, proč se tu polem zabýváme, když má evidentně mnoho omezení a existují lepší datové struktury. Odpověď je prostá: pole je totiž jednoduché. Nemyslíme tím pouze pro nás na pochopení, ale zejména pro samotnou Javu. S polem se rychle pracuje, protože prvky jsou v paměti jednoduše uloženy za sebou, všechny prvky zabírají stejně místa a rychle se k nim přistupuje. Mnoho vnitřních funkčností v Javě proto nějak s polem pracuje nebo pole vrací. Jedná se tedy o klíčovou strukturu.

Pro hromadnou manipulaci s prvky pole se používají cykly.

Práce s polem

V několika dalších krocích si pole deklarujeme, následně ho založíme a na závěr naplníme vlastními daty.

Deklarace pole

Pole deklarujeme pomocí hranatých závorek:

int[] cisla;

Na české klávesnici jsou hranaté závorky ukryté pod Pravým Alt společně s klávesami F a G:

Hranaté závorky - Základní konstrukce jazyka Java

Slovo cisla je samozřejmě název naší proměnné. Nyní jsme však pouze deklarovali, že v proměnné bude pole prvků typu int. Nyní musíme pole založit, abychom ho mohli používat. Pole pojmenováváme vždy množným číslem podle toho, co pole obsahuje.

Založení pole

K založení použijeme klíčové slovo new, které zatím nebudeme vysvětlovat. Spokojíme se s informací, že je to kvůli tomu, že je pole referenční datový typ (můžeme chápat jako složitější typ):

int[] cisla = new int[10];

Nyní máme v proměnné cisla pole o velikosti deseti čísel typu int.

Přístup k prvkům pole

K prvkům pole potom přistupujeme přes hranatou závorku. Pojďme na první index (tedy index 0) uložit číslo 1:

int[] cisla = new int[10];
cisla[0] = 1;

Naplnění pole cyklem

Plnit pole ručně daty by bylo příliš pracné, proto použijeme cyklus a naplníme si pole čísly od 1 do 10. K naplnění použijeme cyklus for:

int[] cisla = new int[10];
for (int i = 0; i < 10; i++) {
    cisla[i] = i + 1;
}

Abychom pole vypsali, můžeme za předchozí kód připsat:

Klikni pro editaci
  • for (int i = 0; i < cisla.length; i++) {
        System.out.print(cisla[i] + " ");
    }
    
    • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

      Pokud tvá aplikace vyžaduje vstup od uživatele, musíš použít Scanner a proměnná se musí jmenovat buďto scanner nebo sc.

    Všimněme si, že pole má konstantu length, kde je uložena jeho délka, tedy počet prvků.

    Výstup programu:

    Konzolová aplikace
    1 2 3 4 5 6 7 8 9 10

    Cyklus foreach

    Můžeme použít zjednodušenou verzi cyklu pro práci s kolekcemi, známou jako tzv. foreach. Ten projede všechny prvky v poli a jeho délku si zjistí sám. Syntaxe cyklu je následující:

    for (datovytyp promenna : kolekce) {
        // příkazy
    }

    Cyklus projede prvky v kolekci (to je obecný název pro struktury, které obsahují více prvků, u nás to bude pole) postupně od prvního do posledního. Prvek máme v každé iteraci cyklu uložený v dané proměnné.

    Přepišme tedy náš dosavadní program pro cyklus foreach. Cyklus foreach nemá řídicí proměnnou, není tedy vhodný pro vytvoření našeho pole a použijeme ho jen pro výpis:

    Klikni pro editaci
    • int[] cisla = new int[10];
      for (int i = 0; i < 10; i++) {
          cisla[i] = i + 1;
      }
      for (int cislo : cisla) {
          System.out.print(cislo + " ");
      }
      
      • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

        Pokud tvá aplikace vyžaduje vstup od uživatele, musíš použít Scanner a proměnná se musí jmenovat buďto scanner nebo sc.

      Výstup programu:

      Konzolová aplikace
      1 2 3 4 5 6 7 8 9 10

      Naplnění pole ručně

      Pole samozřejmě můžeme naplnit i ručně, a to i bez toho, abychom dosazovali postupně do každého indexu. Použijeme k tomu složené závorky a prvky oddělujeme čárkou:

      String[] simpsonovi = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};

      Pole často slouží k ukládání mezivýsledků, které se potom dále v programu používají. Když potřebujeme nějaký výsledek 10x, tak ho nebudeme 10x počítat, ale spočítáme ho jednou a uložíme ho do pole, odkud poté výsledek jen načteme.

      Metody na třídě Arrays

      Java nám poskytuje třídu Arrays, která obsahuje pomocné metody pro práci s poli.

      K jejímu použití je třeba ji naimportovat:

      import java.util.Arrays;

      Pojďme se na metody podívat:

      Metoda sort()

      Jak již název napovídá, metoda sort() nám pole seřadí. Její jediný parametr je pole, které chceme seřadit. Metoda je dokonce tak chytrá, že pracuje podle toho, co máme v poli uložené. Řetězce třídí podle abecedy, čísla podle velikosti. Zkusme si seřadit a vypsat naši rodinku Simpsonů:

      Klikni pro editaci
      • String[] simpsonovi = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
        Arrays.sort(simpsonovi);
        for (String simpson : simpsonovi) {
            System.out.print(simpson + " ");
        }
        
        • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

          Pokud tvá aplikace vyžaduje vstup od uživatele, musíš použít Scanner a proměnná se musí jmenovat buďto scanner nebo sc.

        Výstup programu:

        Konzolová aplikace
        Bart Homer Lisa Maggie Marge

        Zkuste si vytvořit pole čísel a vyzkoušejte si, že metoda opravdu funguje i pro ně.

        Metoda binarySearch()

        Když pole seřadíme, umožní nám v něm Java vyhledávat prvky. Metoda binarySearch() nám vrátí index prvního nalezeného prvku. V případě nenalezení prvku metoda vrátí záporné číslo, jehož přesná hodnota závisí na pozici, kam by daný prvek v poli patřil. Metoda bere dva parametry, prvním je pole, druhým hledaný prvek. Umožníme uživateli zadat jméno Simpsona a poté zkontrolujeme, zda je to opravdu Simpson:

        Klikni pro editaci
        • Scanner scanner = new Scanner(System.in);
          
          String[] simpsonovi = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
          System.out.println("Zadej Simpsona (z rodiny Simpsonů): ");
          String simpson = scanner.nextLine();
          
          Arrays.sort(simpsonovi);
          int pozice = Arrays.binarySearch(simpsonovi, simpson);
          if (pozice >= 0) {
                  System.out.println("Jo, to je Simpson!");
          }
          else {
                  System.out.println("Hele, tohle není Simpson!");
          }
          
          • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

            Pokud tvá aplikace vyžaduje vstup od uživatele, musíš použít Scanner a proměnná se musí jmenovat buďto scanner nebo sc.

          Pole musí být opravdu nejprve setříděné, než metodu zavoláme!

          Výstup programu:

          Konzolová aplikace
          Zadej Simpsona (z rodiny Simpsonů):
          Homer
          Jo, to je Simpson!

          Metoda copyOfRange()

          Metoda copyOfRange() již podle názvu zkopíruje část pole do jiného pole. Prvním parametrem je zdrojové pole, druhým startovní pozice a třetím konečná pozice. Metoda vrací nové pole, které je výsekem původního pole.

          Proměnná délka pole

          Již jsme si říkali, že délku pole můžeme definovat i za běhu programu. Pojďme si to zkusit:

          Scanner scanner = new Scanner(System.in);
          
          System.out.println("Ahoj, spočítám ti průměr známek. Kolik známek zadáš?");
          int pocetZnamek = Integer.parseInt(scanner.nextLine());
          int[] znamky = new int[pocetZnamek];
          for (int i = 0; i < pocetZnamek; i++) {
                  System.out.printf("Zadejte %d. číslo:%n", i + 1);
                  znamky[i] = Integer.parseInt(scanner.nextLine());
          }
          // spočítání průměru
          int soucet = 0;
          for (int znamka : znamky) {
                  soucet += znamka;
          }
          double prumer = soucet / (double)znamky.length;
          
          System.out.printf("Průměr tvých známek je: %.1f", prumer);

          Příkaz soucet += znamka je pouze zkrácený zápis pro soucet = soucet + znamka.

          Při výpisu jsme použili výraz %n. Tento výraz nám zajistí, že máme nový řádek nezávisle na platformě. Například na platformě MacOS se výraz automaticky nahradí za znaky \r. Alternativně můžeme využít například znaky \n, ale je možné, že se na nějaké platformě nový řádek nevytvoří.

          Výstup programu:

          Konzolová aplikace
          Ahoj, spočítám ti průměr známek. Kolik známek zadáš?
          5
          Zadejte 1. číslo: 1
          Zadejte 2. číslo: 2
          Zadejte 3. číslo: 2
          Zadejte 4. číslo: 3
          Zadejte 5. číslo: 5
          Průměr tvých známek je: 2.6

          Tento příklad by šel samozřejmě napsat i bez použití pole, ale co kdybychom chtěli spočítat např. medián? Nebo vypsat zadaná čísla pozpátku? To už by bez pole nešlo. Takto máme v poli k dispozici původní hodnoty a můžeme s nimi neomezeně a jednoduše pracovat.

          U výpočtu průměru si všimněme, že při dělení je před jedním operandem napsáno (double), čímž říkáme, že chceme dělit neceločíselně. Při dělení 3 / 2 dostaneme výsledek 1 a při dělení 3 / 2.0F dostaneme výsledek 1.5. Druhé číslo musí být vždy reálné, aby Java dělila taktéž reálně (na více desetinných míst).

          To by pro dnešek stačilo, můžete si s polem hrát.

          V následujícím kvízu, Kvíz - Podmínky, cykly a pole v Javě, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


           

          Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

          Stáhnout

          Stažením následujícího souboru souhlasíš s licenčními podmínkami

          Staženo 1420x (71.07 kB)
          Aplikace je včetně zdrojových kódů v jazyce Java

           

          Jak se ti líbí článek?
          Před uložením hodnocení, popiš prosím autorovi, co je špatněZnaků 0 z 50-500
          Předchozí článek
          Řešené úlohy k 10.-11. lekci Javy
          Všechny články v sekci
          Základní konstrukce jazyka Java
          Přeskočit článek
          (nedoporučujeme)
          Kvíz - Podmínky, cykly a pole v Javě
          Článek pro vás napsal David Hartinger
          Avatar
          Uživatelské hodnocení:
          1049 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