15. diel - Podmienky v Jave - Ternárny výraz, prepadávací switch
V predchádzajúcom cvičení, Riešené úlohy k 14. lekcii Javy, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnom Java tutoriále si predstavíme 2 ďalšie konštrukcie, ktoré súvisia s podmienkami. Ide o oddychový tutoriál, ktorým túto tému dokončíme.
Ternárny operátor
Často sa nám stáva, že niekde potrebujeme nastaviť 2 rôzne hodnoty podľa toho, či platí nejaká podmienka.
Príklad - Výpis pohlavia
Predstavme si, že máme napr. pohlavie používateľa uložené ako
boolean
. Muž (man) by bol true
a my by sme ho chceli
previesť do textu. S doterajšími znalosťami by sme napísali asi takýto
kód:
{JAVA_CONSOLE}
boolean man = true; // variable determining gender
String genderName;
if (man) {
genderName = "man";
} else {
genderName = "woman";
}
System.out.println(genderName);
{/JAVA_CONSOLE}
Výstup programu je samozrejme nasledujúci:
Konzolová aplikácia
man
Kód je pomerne ukecaný na to, že len prepína medzi dvoma hodnotami. Preto programovacie jazyky často podporujú tzv. ternárny výraz.
Syntax ternárneho výrazu
Pomocou tohto operátora môžeme získať hodnotu podľa platnosti logického výrazu. Zapíšeme ho takto:
(condition) ? fulfilled : unfulfilled
Podmienku vložíme väčšinou do zátvorky ()
, potom nasleduje
otáznik ?
a 2 hodnoty, ktoré sa majú vrátiť. Hodnoty sú
oddelené dvojbodkou :
, prvá hodnota plati
sa vráti,
keď podmienka platí. Druhá hodnota, keď podmienka neplatí. Aké ľahké!
Názov operátora je odvodený
od toho, že má tri časti (podmienka, prvá hodnota a druhá hodnota), preto
ternárny.
Príklad - Výpis pohlavia pomocou ternárneho výrazu
Poďme si ternárny operátor vyskúšať na príklade s pohlavím:
{JAVA_CONSOLE}
boolean man = true; // variable determining gender
String genderName = (man) ? "man" : "woman";
System.out.println(genderName);
{/JAVA_CONSOLE}
Miesto typu boolean
by sme mohli do zátvorky
samozrejme napísať akúkoľvek inú podmienku, napr.
(age >= 18) ? "adult" : "child"
. V prípade
jednoduchých výrazov môžeme zátvorku aj vynechať.
Vnorenie ternárnych operátorov
Ternárne operátory je teoreticky možné zanárať do seba a tým reagovať aj na tri a viac hodnôt. Avšak vo väčšine prípadov vnorovanie skôr kód zneprehľadní, vznikajú totiž dlhé alebo podivne zalomené riadky a nie je na prvý pohľad vidieť, aká časť sa kedy spustí. Ukážme si, ako by sa pomocou vnorovania ternárnych výrazov vyriešil výpis troch smajlíkov:
{JAVA_CONSOLE}
String smiley= ":)"; // variable determining smiley
String mood = (smiley.equals(":)")) ? "happy" : (smiley.equals(":(")) ? "sad" : "unknown";
System.out.println(mood);
{/JAVA_CONSOLE}
Pre príklad vyššie by bolo lepšie vytvoriť vlastnú metódu, čo si ale ukážeme až v nadväzujúcom kurze objektovo orientovaného programovania.
Konštrukcia switch
s
prepadávaním
S konštrukciou switch
sme sa už stretli v lekcii Podmienky
(vetvenie). Dnes si ukážeme jej ďalšie použitie. Na rozdiel od
ternárneho operátora ide skôr o historickú funkčnosť, pre ktorú dnes nie
je veľa rozumného využitia. Stále je ale súčasťou štandardnej gramatiky
Javy a môžete na ňu naraziť v cudzích zdrojových kódoch.
Príklad - Štvrťrok
Predpokladajme, že chceme podľa mesiaca v roku zistiť, aký je štvrťrok.
Pomocou blokov if
a else
by príklad vyzeral
nasledovne:
{JAVA_CONSOLE}
int month = 2;
if (month >= 1 && month <= 3) {
System.out.println("It's the first quarter.");
}
else if (month >= 4 && month <= 6) {
System.out.println("It's the second quarter.");
}
else if (month >= 7 && month <= 9) {
System.out.println("It's the third quarter.");
}
else if (month >= 10 && month <= 12) {
System.out.println("It's the fourth quarter.");
}
{/JAVA_CONSOLE}
Ako ale použiť konštrukciu switch
pre takýto príklad?
Možno by vás napadol nasledujúci zápis:
{JAVA_CONSOLE}
int month = 11;
switch (month) {
case 1:
System.out.println("It's the first quarter.");
break;
case 2:
System.out.println("It's the first quarter.");
break;
case 3:
System.out.println("It's the first quarter.");
break;
case 4:
System.out.println("It's the second quarter.");
break;
case 5:
System.out.println("It's the second quarter.");
break;
case 6:
System.out.println("It's the second quarter.");
break;
case 7:
System.out.println("It's the third quarter.");
break;
case 8:
System.out.println("It's the third quarter.");
break;
case 9:
System.out.println("It's the third quarter.");
break;
case 10:
System.out.println("It's the fourth quarter.");
break;
case 11:
System.out.println("It's the fourth quarter.");
break;
case 12:
System.out.println("It's the fourth quarter.");
break;
}
{/JAVA_CONSOLE}
Príklad funguje spoľahlivo, problémom však je, že sme si týmto zápisom veľmi nepomohli. Podobnému repetitívnemu kódu by sme sa vždy mali vyhýbať.
Prepadávanie
Skúsme to ešte raz a využime tzv. prepadávanie. Pokiaľ
potrebujeme vo viacerých blokoch case
vykonávať rovnaký kód,
stačí tieto bloky vložiť pod seba a neukončovať každý blok pomocou
príkazu break
, ale celú skupinu bloku jedným príkazom
break
. Neukončené bloky tak prepadnú a vykoná sa kód
spoločný pre viac blokov:
{JAVA_CONSOLE}
int month = 11;
switch (month) {
case 1:
case 2:
case 3:
System.out.println("It's the first quarter.");
break;
case 4:
case 5:
case 6:
System.out.println("It's the second quarter.");
break;
case 7:
case 8:
case 9:
System.out.println("It's the third quarter.");
break;
case 10:
case 11:
case 12:
System.out.println("It's the fourth quarter.");
break;
}
{/JAVA_CONSOLE}
Ukážka výstupu aplikácie:
Konzolová aplikácia
It's the fourth quarter.
Tento zápis je už oveľa prehľadnejší. Konštrukcia switch
má však pridanú hodnotu v prípade, keď nemôžeme použiť
väčší/menší a ide o zoznam hodnôt, tu je to skôr redundantný kód plný
prázdnych case
.
Java podporuje prepadávanie ako prázdnych
case
, tak na rozdiel od iných jazykov aj case
s
ďalším kódom. To je častá príčina nechcených chýb (zabudnutých
break
), ktoré sa veľmi ťažko hľadajú.
Prepadávanie používajte v konštrukcii switch
len pokiaľ k
nemu máte dobrý dôvod, ale je dôležité, aby ste ho vedeli čítať, keď
naň niekde narazíte.
Vylepšená konštrukcia
Od Javy verzie 12 je možné tiež využiť vylepšenú konštrukciu
switch
. Zápis vyššie by sa dal ešte viac skrátiť:
{JAVA_CONSOLE}
int month = 11;
switch (month) {
case 1, 2, 3 -> System.out.println("It's the first quarter.");
case 4, 5, 6 -> System.out.println("It's the second quarter.");
case 7, 8, 9 -> System.out.println("It's the third quarter.");
case 10, 11, 12 -> System.out.println("It's the fourth quarter.");
}
{/JAVA_CONSOLE}
V budúcej lekcii, Cykly v Jave do tretice - do-while, break a continue, nás čaká ďalšia syntax týkajúca sa cyklov, na ktorú môžeme naraziť v cudzích zdrojových kódoch.