BF Summer sales
Pouze tento týden sleva až 80 % na HTML & CSS a JavaScript
80 % bodů zdarma na online výuku díky naší Letní akci!

Lekce 11 - Cykly v Javě podruhé - do-while, break a continue

V minulé lekci, Podmínky v Javě podruhé - Ternární výraz, propadávací switch, jsme se věnovali další syntaxi podmínek.

Na úvod by bylo dobré podotknout, že dnešní lekce obsahuje méně používané praktiky a slouží hlavně k tomu, aby vás nepřekvapily v cizím kódu. Není příliš důležité, abyste je sami uměli používat.

do...while

Cyklus while již dobře známe. Méně používaný do...while se liší pouze tím, že se vždy vykoná nejméně jednou. Jeho podmínka je totiž umístěna až za tělem cyklu. Vypadá tedy takto:

do
{
    // kód...
} while (podmínka)

Příklad

Použití do-while cyklu si ukažme na naší kalkulačce z lekce o cyklech.

Varianta s while

V kalkulačce jsme použili cyklus while, který umožnil celý program opakovat a tak zadávat další a další příklady. Kód vypadal takto (jedná se o verzi s konstrukcí switch):

Scanner sc = new Scanner(System.in, "Windows-1250");

System.out.println("Vítejte v kalkulačce");
String pokracovat = "ano";
while (pokracovat.equals("ano")) {
    System.out.println("Zadejte první číslo:");
    float a = Float.parseFloat(sc.nextLine());
    System.out.println("Zadejte druhé číslo:");
    float b = Float.parseFloat(sc.nextLine());
    System.out.println("Zvolte si operaci:");
    System.out.println("1 - sčítání");
    System.out.println("2 - odčítání");
    System.out.println("3 - násobení");
    System.out.println("4 - dělení");
    int volba = Integer.parseInt(sc.nextLine());
    float vysledek = 0;
    switch (volba) {
        case 1:
                vysledek = a + b;
        break;
        case 2:
                vysledek = a - b;
        break;
        case 3:
                vysledek = a * b;
        break;
        case 4:
                vysledek = a / b;
        break;
    }
    if ((volba > 0) && (volba < 5)) {
        System.out.println("Výsledek: " + vysledek);
    } else {
        System.out.println("Neplatná volba");
    }
    System.out.println("Přejete si zadat další příklad? [ano/ne]");
    pokracovat = sc.nextLine();
}
System.out.println("Děkuji za použití kalkulačky.");

Všimněte si, že jsme se u této varianty s while museli zamyslet nad výchozí hodnotou proměnné pokracovat, které jsme nastavili hodnotu "ano", aby podmínka byla splněna pro první průchod cyklem. Vymyslet výchozí hodnotu může být ale někdy poměrně složité a třeba i vyžadovat pomocnou proměnnou.

Varianta s do-while

Když použijeme cyklus do-while, tak výchozí hodnotu dané proměnné nemusíme řešit:

Scanner sc = new Scanner(System.in, "Windows-1250");

System.out.println("Vítejte v kalkulačce");
String pokracovat;
do {
    System.out.println("Zadejte první číslo:");
    float a = Float.parseFloat(sc.nextLine());
    System.out.println("Zadejte druhé číslo:");
    float b = Float.parseFloat(sc.nextLine());
    System.out.println("Zvolte si operaci:");
    System.out.println("1 - sčítání");
    System.out.println("2 - odčítání");
    System.out.println("3 - násobení");
    System.out.println("4 - dělení");
    int volba = Integer.parseInt(sc.nextLine());
    float vysledek = 0;
    switch (volba) {
        case 1:
                vysledek = a + b;
        break;
        case 2:
                vysledek = a - b;
        break;
        case 3:
                vysledek = a * b;
        break;
        case 4:
                vysledek = a / b;
        break;
    }
    if ((volba > 0) && (volba < 5)) {
        System.out.println("Výsledek: " + vysledek);
    }
    else {
        System.out.println("Neplatná volba");
    }
    System.out.println("Přejete si zadat další příklad? [ano/ne]");
    pokracovat = sc.nextLine();
} while (pokracovat.equals("ano"))
System.out.println("Děkuji za použití kalkulačky.");

break a continue

Běh cyklu je potřeba někdy přerušit, k tomu máme následující 2 klíčová slova.

break

Příkaz break ukončuje aktuální cyklus. Používá se nejčastěji pokud pomocí cyklu nalezneme nějakou položku v kolekci a dále již v jejím procházení nechceme pokračovat. Nebudeme tak dále zbytečně prohledávat zbytek kolekce, když již máme to, co jsme hledali.

Příklad

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Představme si, že máme velké a malé štítky na sklenice a chceme použít na všechny sklenice buď jedny nebo druhé. Zajímá nás tedy, zda se text všech popisek vejde na malé štítky. Napíšeme program, který zjistí, zda je v poli slovo delší než 6 znaků. Pokud ano, musíme použít větší štítky.

Začneme cyklem procházet jednotlivá slova a jakmile najdeme slovo delší než 6 znaků, tak si uložíme jeho index. Zatím stále nic nového pod sluncem. V tu samou chvíli ovšem pomocí break cyklus ukončíme.

Ukázka použití break:

String[] seznamOvoce = {"Jablka", "Hrušky", "Švestky", "Meruňky", "Jahody", "Třešně"};
int hledanyIndex = -1;

for (int i = 0; i < seznamOvoce.length; i++) {
    if (seznamOvoce[i].length() > 6) {
        hledanyIndex = i;
        break;
    }
}

if (hledanyIndex >= 0)
    System.out.println("První slovo delší než 6 znaků: " + seznamOvoce[hledanyIndex]);

Výstup:

Konzolová aplikace
První slovo delší než 6 znaků: Švestky

Příkaz break se v praxi často nahrazuje příkazem return za předpokladu, že je kód v naší vlastní metodě. Vlastní metody se ale naučíme deklarovat až v navazujícím kurzu Základy objektově orientovaného programování v Javě. Potom break doporučuji spíše nepoužívat, správnější varianta je kód pro práci s kolekcí vyčlenit do samostatné funkce.

continue

Příkaz continue je podobný break. Používá se však k ukončení pouze aktuální iterace (průběhu) cyklu a ne celého cyklu. Cyklus poté rovnou přechází na další iteraci. Použití continue můžeme najít např. při validování položek při procházení nějaké kolekce.

Příklad

Představme si, že máme od uživatele zadaná čísla a tato čísla chceme sečíst. Uživatel tato čísla zadá jako jeden řetězec, kde každé číslo je oddělené čárkou. Bohužel musíme počítat i s tím, že uživatel zadá místo čísla nějaký nesmysl. Řešení by mohlo vypadat následovně:

String cislaRetezec = "10,50,ab10cd,30,9";
// rozložení řetězce do pole
String[] cislaPole = cislaRetezec.split(",");
int soucet = 0;
for (String cislo : cislaPole) {
    // Ověření, že proměnná neobsahuje žádné nečíselné znaky
    if(!cislo.matches("\\d+"))
        continue;
    // převedení řetězce na celé číslo
    int celeCislo = Integer.parseInt(cislo);

    soucet += celeCislo;
}
System.out.println("Součet je: " + soucet);

Výstup:

Konzolová aplikace
Součet je: 99

Program sečte všechny správně zadané hodnoty. Formát řetězce ověřujeme pomocí metody matches(), která pro parametr "\\d+" vrátí true, pokud je text jen celé kladné číslo. U nesprávně zadaných hodnot je aktuální iterace ukončena. Místo continue bychom samozřejmě mohli použít jen příkaz if, kód bychom tím ovšem zbytečně zanořili.

Ověření, že zadaná hodnota je číslo lze provést více způsoby. Standardně se volání metody parseInt() obalí do try-catch bloku. Zatím ale nebyla o výjimkách řeč, proto jsme zavolali matches(), což je přeci jen jednodušší. Hodnota \\d říká, že se vyskytne číselná hodnota. Pomocí prvního lomítka se vyescapuje druhé lomítko. Znak + na konci říká, že takových znaků může být jeden a více.

Zkrácený zápis cyklu for

Následující konstrukce jsou zde pro ukázku co vše je možné potkat v cizích kódech a není dobrý důvod je používat!

Cyklus for je možné zapsat takto zkráceně, bez těla cyklu:

for (int i = 0; i < 10; System.out.print(i++));

Výstup:

Konzolová aplikace
0123456789

Psát logiku průběhu běhu cyklu i logiku v cyklu na jeden řádek ovšem není intuitivní. Navíc se tak může snadno zapomenout na inkrementaci proměnné nebo ji inkrementovat vícekrát. 

Dokonce není nutné v hlavičce cyklu for uvádět jakýkoliv příkaz:

for (;;) {
    // nekonečný cyklus
}

Tento zápis je stejný jako:

while (true) {
    // nekonečný cyklus
}

Oba výše deklarované cykly běží do nekonečna a můžete je potkat ve špatně napsaných zdrojových kódech spolu s příkazy break, které z nich potom za nějakých podmínek vyskakují.

Jakmile podmínka není přímo v deklaraci cyklu, je poměrně nepřehledné zjistit, kdy cyklus vůbec skončí a snadné udělat z takového cyklu nechtěně nekonečný. To platí zvláště, když z cyklu vyskakujeme více podmínkami a nepokryjeme všechny možné případy.

Ač dnešní lekce obsahovala standardní gramatiku Javy pro cykly, z nových konstrukcí používejte pouze do-while a continue. Přechodně ještě můžete používat break, než se dostaneme k objektům :)

V příští lekci, Vícerozměrná pole v Javě, se tedy uvidíme u vícerozměrných polí.


 

Předchozí článek
Podmínky v Javě podruhé - Ternární výraz, propadávací switch
Všechny články v sekci
Základní konstrukce jazyka Java
Článek pro vás napsal Ing. Petr Štechmüller
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje primárně programování v Jave, ale nebojí se ani webových technologií.
Aktivity (3)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!