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
:
{JAVA_CONSOLE}
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]);
}
{/JAVA_CONSOLE}
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ě:
{JAVA_CONSOLE}
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);
{/JAVA_CONSOLE}
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:
{JAVA_CONSOLE}
for (int i = 0; i < 10; System.out.print(i++));
{/JAVA_CONSOLE}
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.