Vezérlési szerkezetek
If-else, switch kifejezések, for, while, do-while ciklusok, break, continue és címkézett break
Vezérlési szerkezetek
A vezérlési szerkezetek határozzák meg a program végrehajtási sorrendjét. Nélkülük minden kód egyetlen egyenes vonalú utasítássorozat lenne.
1. Definíció
Mi ez? A vezérlési szerkezetek (control structures) olyan nyelvi elemek, amelyek meghatározzák, hogy a program utasításai milyen sorrendben hajtódnak végre — feltételesen, ismételten, vagy éppen átugorva bizonyos blokkokat.
Miért fontos? Minden valós program tartalmaz döntéseket és ismétléseket. Az if, switch, for, while és társaik nélkül nem lehetne üzleti logikát, validációt, adatfeldolgozást vagy bármilyen dinamikus viselkedést implementálni.
Hol használjuk?
- Üzleti szabályok kiértékelése (
if/else,switch) - Kollekciók és tömbök bejárása (
for,for-each,while) - Input validáció (
do-while) - Állapotgépek és routing (
switch expression) - Komplex iterációk vezérlése (
break,continue, labeled break)
2. Alapfogalmak
2.1 Feltételes elágazások
| Szerkezet | Leírás | Mikor használd |
|---|---|---|
if / else |
Alapvető feltételes elágazás | 1–3 ág, boolean feltétel |
if / else if / else |
Többirányú feltétel | Több kizáró feltétel |
switch (classic) |
Értékalapú elágazás | Egy változó több konkrét értéke |
switch expression (Java 14+) |
Értéket visszaadó switch | Változóhoz rendelés, tisztább szintaxis |
Ternary ? : |
Inline feltétel | Egyszerű érték-hozzárendelés |
2.2 Ciklusok
| Szerkezet | Leírás | Tipikus használat |
|---|---|---|
for |
Számlálós ciklus | Ismert iterációszám, index szükséges |
for-each (for(T x : coll)) |
Iterátor-alapú ciklus | Kollekció/tömb teljes bejárása |
while |
Elöltesztelő ciklus | Feltételtől függő ismétlés |
do-while |
Hátultesztelő ciklus | Legalább 1× végrehajtás szükséges |
2.3 Vezérlésátadó utasítások
| Kulcsszó | Hatás |
|---|---|
break |
Kilép az aktuális ciklusból vagy switch-ből |
continue |
Átugorja az aktuális iteráció hátralévő részét |
return |
Kilép a metódusból (és opcionálisan értéket ad vissza) |
yield (Java 14+) |
Értéket ad vissza egy switch expression blokkból |
labeled break |
Kilép egy megjelölt (labeled) külső ciklusból |
labeled continue |
A megjelölt külső ciklus következő iterációjára ugrik |
2.4 Switch evolúciója
Java 1.0 → classic switch (int, char)
Java 5 → enum támogatás
Java 7 → String támogatás
Java 14 → switch expression (preview → standard)
Java 17 → pattern matching switch (preview)
Java 21 → pattern matching switch (finalized)
3. Gyakorlati alkalmazás
Melyik ciklust válaszd?
| Szituáció | Ajánlott szerkezet |
|---|---|
| Tömb/lista teljes bejárása, index nem kell | for-each |
| Index szükséges vagy léptetés nem +1 | for |
| Feltételtől függő ismétlés, 0× is lehet | while |
| Legalább 1× végre kell hajtani (pl. menu) | do-while |
| Végtelen ciklus szerviz-loophoz | while(true) + break |
Mikor `switch` vs `if-else`?
switch: egyetlen változó több konkrét értéke, enum routing, állapotgépekif-else: boolean kifejezések, tartományellenőrzés (x > 10), több változó kombinációjaswitchexpression (Java 14+): ha az elágazás eredménye egy érték- Pattern matching switch (Java 21+): típusellenőrzés + casting egyben
4. Kódpéldák
4.1 Classic switch — ❌ Fall-through hiba
// ❌ ROSSZ — hiányzó break, fall-through bug
switch (day) {
case MONDAY:
System.out.println("Hétfő");
// break hiányzik!
case TUESDAY:
System.out.println("Kedd"); // MONDAY esetén is kiíródik!
break;
default:
System.out.println("Egyéb nap");
}
// ✅ JÓ — explicit break minden ágban
switch (day) {
case MONDAY:
System.out.println("Hétfő");
break;
case TUESDAY:
System.out.println("Kedd");
break;
default:
System.out.println("Egyéb nap");
}
4.2 Switch expression (Java 14+)
// ✅ Modern switch expression — nincs fall-through, értéket ad vissza
String type = switch (statusCode) {
case 200, 201 -> "Success";
case 301, 302 -> "Redirect";
case 404 -> "Not Found";
case 500 -> "Server Error";
default -> "Unknown";
};
4.3 Switch expression `yield`-del
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
default -> {
String s = day.toString();
int result = s.length();
yield result; // yield adja vissza a block értékét
}
};
4.4 Pattern matching switch (Java 21+)
// ✅ Típusellenőrzés + casting switch-ben
static String format(Object obj) {
return switch (obj) {
case Integer i -> String.format("int: %d", i);
case Long l -> String.format("long: %d", l);
case String s -> String.format("String: %s", s);
case null -> "null";
default -> obj.toString();
};
}
4.5 Guarded pattern (Java 21+)
static String classify(Shape shape) {
return switch (shape) {
case Circle c when c.radius() > 100 -> "nagy kör";
case Circle c -> "kis kör";
case Rectangle r when r.area() > 1000 -> "nagy téglalap";
case Rectangle r -> "kis téglalap";
default -> "ismeretlen";
};
}
4.6 Labeled break — többszintű ciklus elhagyása
// ✅ Labeled break a külső ciklusból való kilépéshez
outer:
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == target) {
System.out.println("Megtalálva: [" + i + "][" + j + "]");
break outer; // a KÜLSŐ ciklusból lép ki
}
}
}
4.7 Off-by-one hiba
// ❌ ROSSZ — ArrayIndexOutOfBoundsException
for (int i = 0; i <= arr.length; i++) { // <= helyett < kell
System.out.println(arr[i]);
}
// ✅ JÓ
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
4.8 Végtelen ciklus — break-kel kontrollálva
// ✅ Input validáció do-while ciklussal
int value;
do {
System.out.print("Adj meg egy pozitív számot: ");
value = scanner.nextInt();
} while (value <= 0);
5. Trade-off-ok
| Szempont | Részletek |
|---|---|
| Olvashatóság | for-each > for > while a kollekció bejárásnál. switch expression > if-else lánc ha 4+ ág van. |
| Teljesítmény | A JIT compiler a legtöbb ciklust azonos natív kódra optimalizálja. for-each tömbre ugyanaz mint az indexelt for. |
switch vs if-else |
A switch egész és String esetén tableswitch/lookupswitch bytecode-ot generál — sok ág esetén gyorsabb mint az if-else lánc. |
| Fall-through | Classic switch fall-through hasznos lehet szándékos csoportosításra, de hibaforrás. Switch expression-ben nincs fall-through. |
| Labeled break | Erős eszköz, de túlzott használata nehezen olvashatóvá teszi a kódot — refaktoráld metódusba. |
6. Gyakori hibák
| Hiba | Leírás | Megelőzés |
| -------------------------------- | -------------------------------------------------- | ------------------------------------------------ | -------------------------------------------- | ----------------------------------------------------- |
| Hiányzó break | Classic switch-ben fall-through | Használj switch expression-t (Java 14+) |
| Off-by-one | <= helyett < (vagy fordítva) tömb indexelésnél | Használj for-each-et ha index nem kell |
| Végtelen ciklus | A ciklusfeltétel sosem lesz false | Mindig ellenőrizd, hogy a ciklusváltozó változik |
| Boolean lusta kiértékelés | && és | | short-circuit — mellékhatások elveszhetnek | Ne használj mellékhatásos kifejezéseket feltételekben |
| Módosítatlan ciklusváltozó | while ciklusban elfelejtjük növelni | Preferáld a for ciklust ha számláló kell |
| Null check hiánya switch-ben | Java 21 előtt NullPointerException | Java 21+ case null -> |
7. Senior szintű tudás
7.1 Switch expression mint exhaustive match
Java 14+-tól a switch expression kötelezően exhaustive — minden lehetséges értéket le kell fedni, különben fordítási hiba. Enum-oknál ez azt jelenti, hogy vagy minden enum konstanst kezeled, vagy van default ág.
7.2 Sealed classes + switch (Java 17/21)
sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double r) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double a, double b, double c) implements Shape {}
// Exhaustive — nem kell default ha minden permitted class-t kezeled
double area(Shape shape) {
return switch (shape) {
case Circle c -> Math.PI * c.r() * c.r();
case Rectangle r -> r.w() * r.h();
case Triangle t -> {
double s = (t.a() + t.b() + t.c()) / 2;
yield Math.sqrt(s * (s - t.a()) * (s - t.b()) * (s - t.c()));
}
};
}
7.3 JIT optimalizációk ciklusokra
- Loop unrolling: a JIT kicsomagolja a kis fix méretű ciklusokat
- Loop vectorization: SIMD utasításokat használ ahol lehetséges
- Bounds check elimination: ha bizonyítható, hogy az index mindig érvényes, a JIT eltávolítja a határellenőrzéseket
- Loop inversion:
while-tdo-while-lá alakítja a jobb branch prediction érdekében
7.4 Bytecode szinten
tableswitch: összefüggő értékkészletre (O(1) lookup)lookupswitch: szórt értékkészletre (O(log n) binary search)- String switch:
hashCode()alapúlookupswitch+equals()ellenőrzés
8. Szójegyzék
| Magyar kifejezés | Angol kifejezés | Jelentés |
|---|---|---|
| Vezérlési szerkezet | Control structure | A végrehajtási sorrend irányítása |
| Feltételes elágazás | Conditional branch | if/else, ternary |
| Ciklus | Loop | Ismétlődő végrehajtás |
| Elöltesztelő ciklus | Pre-test loop | while — feltétel előbb |
| Hátultesztelő ciklus | Post-test loop | do-while — feltétel utóbb |
| Címkézett break | Labeled break | Külső ciklusból kilépés |
| Fall-through | Fall-through | Switch ág "átesés" a következőbe |
| Switch expression | Switch expression | Értéket visszaadó switch (Java 14+) |
| Pattern matching | Pattern matching | Típusellenőrzés + destrukturálás |
| Exhaustive | Exhaustive | Teljes lefedés (minden eset kezelve) |
| Guarded pattern | Guarded pattern | when feltételes pattern |
| Yield | Yield | Blokk-értéket visszaadó kulcsszó |
9. Gyorsreferencia
if/else— boolean feltételek, 1–3 ágswitch(classic) — egy változó konkrét értékei, vigyázz abreak-reswitchexpression (Java 14+) —->szintaxis, nincs fall-through, értéket ad vissza- Pattern matching switch (Java 21+) — típusellenőrzés,
whenguard,case null for— ismert iterációszám, index szükségesfor-each— kollekció/tömb bejárása, nincs indexwhile— 0 vagy több ismétlés, feltétel elöldo-while— legalább 1× végrehajtás, feltétel hátulbreak— kilépés ciklusból/switch-bőlcontinue— ugrás a következő iterációrareturn— kilépés metódusbólyield— érték visszaadása switch expression blokkból- Labeled
break/continue— többszintű ciklusok vezérlése - Sealed classes + switch — exhaustive pattern matching,
defaultnélkül - JIT:
tableswitch= O(1),lookupswitch= O(log n)
🎮 Játékok
8 kérdés