NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 16 - Cykly v Javě potřetí - do-while, break a continue

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

V dnešním Java tutoriálu se podíváme na cyklus do-while, příkazy break a continue a také na zkrácený zápis již probraného cyklu for. Tutoriál obsahuje méně používané praktiky a slouží hlavně k tomu, aby vás nepřekvapily v cizím kódu. Zatím není příliš důležité, abyste je sami uměli používat.

Cyklus 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 – Kalkulačka

Použití do-while cyklu si ukažme na naší kalkulačce z lekce Cykly v Javě.

Varianta s while

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

Scanner scanner = new Scanner(System.in);

System.out.println("Vítejte v kalkulačce");
String pokracovat = "ano";
while (pokracovat.equals("ano")) {
    System.out.println("Zadejte první číslo:");
    double a = Double.parseDouble(scanner.nextLine());
    System.out.println("Zadejte druhé číslo:");
    double b = Double.parseDouble(scanner.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(scanner.nextLine());
    double 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 = scanner.nextLine();
}
System.out.println("Děkuji za použití kalkulačky.");

Všimněme si, že jsme se u této varianty s while museli zamyslet nad výchozí hodnotou proměnné pokracovat. Té jsme nastavili hodnotu ano, aby podmínka byla splněna při prvním průchodu 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. V tomto případě je vhodnější využít cyklus do-while.

Varianta s do-while

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

Scanner scanner = new Scanner(System.in);

System.out.println("Vítejte v kalkulačce");
String pokracovat;
do {
    System.out.println("Zadejte první číslo:");
    double a = Double.parseDouble(scanner.nextLine());
    System.out.println("Zadejte druhé číslo:");
    double b = Double.parseDouble(scanner.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(scanner.nextLine());
    double 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 = scanner.nextLine();
} while (pokracovat.equals("ano"));
System.out.println("Děkuji za použití kalkulačky.");

Příkazy break a continue

Běh cyklu je potřeba někdy přerušit, k čemuž nám slouží následující dvě klíčová slova.

Příkaz break

Příkaz break ukončuje aktuální cyklus. Používá se nejčastěji v situaci, kdy 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 s využitím break

Představme si, že máme velké a malé štítky na sklenice a chceme použít na všechny sklenice buď jedny štítky, 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ž šest znaků. Pokud ano, musíme použít větší štítky.

Začneme cyklem procházet jednotlivá slova, a jakmile najdeme slovo delší než šest znaků, uložíme si jeho index. Zatím stále nic nového pod sluncem. Avšak v téže chvíli cyklus pomocí příkazu break ukončíme.

Ukázka použití příkazu 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 programu:

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

Příkaz break se v praxi často nahrazuje příkazem return za předpokladu, že kód je 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ě. Poté už příkaz break doporučujeme spíše nepoužívat, správnější variantou je kód pro práci s kolekcí vyčlenit do samostatné funkce.

Příkaz continue

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

Příklad s využitím continue

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 je každé číslo 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 retezec = "10,50,ab10cd,30,9";
// rozložení řetězce do pole
String[] polozky = retezec.split(",");
int soucet = 0;
for (String polozka : polozky) {
    // Ověření, že proměnná neobsahuje žádné nečíselné znaky
    if (!polozka.matches("\\d+")) {
        continue;
    }
    // převedení řetězce na celé číslo
    int cislo = Integer.parseInt(polozka);

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

Výstup programu:

Konzolová aplikace
Součet je: 99

Program sečte všechny správně zadané hodnoty. Formát řetězce ověřujeme pomocí metody matches(). Než se budeme naplno těmito regulárními výrazy zabývat, bude nám stačit informace, že výraz \\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 příkazu continue bychom samozřejmě mohli použít jen příkaz if.

Zkrácený zápis cyklu for

Následující konstrukce jsou zde pouze pro ukázku, s čím vším je možné se setkat v cizích kódech. Tyto konstrukce není dobrý nápad 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 může snadno zapomenout na inkrementaci proměnné nebo proměnnou inkrementovat vícekrát. 

V hlavičce cyklu for dokonce není nutné uvádět jakýkoli příkaz:

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

Tento zápis je stejný jako:

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

Oba výše deklarované cykly běží donekonečna a můžete se s nimi setkat 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čí. Potom je velmi snadné z takového cyklu nechtěně udělat nekonečný. To platí zvláště v případě, kdy z cyklu vyskakujeme více podmínkami a nepokryjeme všechny možné případy.

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

V příští lekci, Matematické funkce v Javě a knihovna Math, se podíváme na matematické funkce a základní kurz úplně zakončíme.


 

Předchozí článek
Podmínky v Javě potřetí - Ternární výraz, propadávací switch
Všechny články v sekci
Základní konstrukce jazyka Java
Přeskočit článek
(nedoporučujeme)
Matematické funkce v Javě a knihovna Math
Článek pro vás napsal Petr Štechmüller
Avatar
Uživatelské hodnocení:
725 hlasů
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity