JavaRush /Java-Blog /Random-DE /Switch-Anweisung in Java

Switch-Anweisung in Java

Veröffentlicht in der Gruppe Random-DE
Stellen Sie sich vor, Sie stehen an einer Gabelung, wie ein Held aus einem berühmten Gemälde. Wenn Sie nach links gehen, verlieren Sie Ihr Pferd; wenn Sie nach rechts gehen, gewinnen Sie Wissen. Wie programmiert man eine solche Situation? Sie wissen höchstwahrscheinlich bereits, dass wir eine solche Entscheidung mithilfe der If-Then- und If-Then-Else- Konstrukte treffen .
if (turn_left) {
    System.out.println(«Коня потеряешь»);
}
if (turn_right) {
    System.out.println(“Знания обретёшь”);
}
else
    System.out.println(“Так и будешь стоять?);
Was wäre, wenn es nicht zwei solcher Spuren gäbe, sondern zehn? Gibt es einen Weg „nach rechts“, „etwas nach links“, „etwas mehr nach links“ usw. in der Menge von 10 Stück? Stellen Sie sich vor, wie Ihr Wenn-Dann-Sonst- Code in dieser Version wachsen wird!
if (вариант1)
{}
else if (вариант2)
{}else if (вариантN).
Sie haben also nicht eine Abzweigung von Bedingungen, sondern mehrere, sagen wir, 10 (wichtig ist hier, dass die Anzahl der Abzweigungen begrenzt ist). Für solche Situationen gibt es einen speziellen Auswahloperator – switch case java .
switch (ВыражениеДляВыбора) {
           case  (Значение1):
               Код1;
               break;
           case (Значение2):
               Код2;
               break;
...
           case (ЗначениеN):
               КодN;
               break;
           default:
               КодВыбораПоУмолчанию;
               break;
       }
Die Ausführungsreihenfolge in der Anweisung lautet wie folgt:
  • Der SelectionExpression wird ausgewertet. Als nächstes vergleicht die switch-Anweisung den resultierenden Ausdruck mit dem nächsten Wert (in der aufgeführten Reihenfolge).
  • Wenn SelectExpression mit Value übereinstimmt, wird der Code nach dem Doppelpunkt ausgeführt.
  • Wenn das Break- Konstrukt angetroffen wird , wird die Steuerung außerhalb des Switch-Befehls übertragen.
  • Wenn keine Übereinstimmungen zwischen ExpressionForSelection und Values ​​gefunden werden, wird die Steuerung an den DefaultSelectionCode übergeben.
Wichtige Punkte
  • Der SelectionExpression-Typ für eine Schalterauswahlanweisung in Java muss einer der folgenden sein:

    • Byte , kurz , char , int .
    • Ihre Wrapper sind Byte , Short , Character , Integer .
    • String (seit Java 7).
    • Aufzählung ( Enum ).
  • Der Standardblock ist optional . Wenn SelectionExpression und Values ​​​​nicht übereinstimmen, wird keine Aktion ausgeführt.
  • breakbreak ist optional; wenn es nicht vorhanden ist, wird der Code bis zur ersten angetroffenen switch-Anweisung oder bis zum Ende weiter ausgeführt (wobei weitere Wertevergleiche in case-Blöcken ignoriert werden) .
  • Wenn es notwendig ist, denselben Code für mehrere Auswahloptionen auszuführen, geben wir zur Vermeidung von Duplikaten mehrere entsprechende Werte davor in aufeinanderfolgenden Case- Blöcken an .

Fahren wir mit der Praxis der Verwendung der Switch-Anweisung in Java fort

Keine Sorge, wir sind mit der Theorie fertig und nach weiteren Beispielen wird alles viel klarer. Also lasst uns anfangen. Schauen wir uns ein Beispiel aus der Astronomie über die Planeten des Sonnensystems an. Gemäß den neuesten internationalen Vorschriften werden wir Pluto (aufgrund der Eigenschaften seiner Umlaufbahn) ausschließen. Denken wir daran, dass sich unsere Planeten von der Sonne aus in der folgenden Reihenfolge befinden: Merkur, Venus, Erde, Mars, Jupiter, Saturn, Uranus und Neptun. Erstellen wir eine Java-Methode, die als Eingabe die Seriennummer des Planeten (relativ zur Entfernung von der Sonne) empfängt und als Ausgabe die Hauptzusammensetzung der Atmosphäre dieses Planeten in Form einer Liste <String> angibt . Ich möchte Sie daran erinnern, dass einige Planeten eine ähnliche Atmosphärenzusammensetzung haben. So enthalten Venus und Mars hauptsächlich Kohlendioxid, Jupiter und Saturn bestehen aus Wasserstoff und Helium und Uranus und Neptun verfügen neben dem letzten Gaspaar auch über Methan. Unsere Funktion:
public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add(„Keine Atmosphäre“);
            break;
        case 2:
        case 4: result.add("Kohlendioxid");
            break;
        case 3: result.add("Kohlendioxid");
            result.add("Stickstoff");
            result.add("Sauerstoff");
            break;
        case 5:
        case 6: result.add("Wasserstoff");
            result.add("Helium");
            break;
        case 7:
        case 8: result.add("Methan");
            result.add("Wasserstoff");
            result.add("Helium");
            break;
        default:
            break;
    }
    return result;
}
Bitte beachten Sie: Wir haben denselben Code mit Planeten mit identischer atmosphärischer Zusammensetzung verglichen. Und wir haben dies erreicht, indem wir aufeinanderfolgende Fallkonstruktionen verwendet haben . Wenn wir also die Zusammensetzung der Atmosphäre unseres Heimatplaneten ermitteln möchten, rufen wir unsere Methode mit Parameter 3 auf:
getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) вернет нам [Углекислый газ, Азот, Кислород].
Experimentieren Sie mit break. Was passiert, wenn wir alle break- Anweisungen entfernen ? Versuchen wir es in der Praxis:
public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add(„Keine Atmosphäre“);
        case 2:
        case 4: result.add("Kohlendioxid");
        case 3: result.add("Kohlendioxid");
            result.add("Stickstoff");
            result.add("Sauerstoff");
        case 5:
        case 6: result.add("Wasserstoff");
            result.add("Helium");
        case 7:
        case 8: result.add("Methan");
            result.add("Wasserstoff");
            result.add("Helium");
        default:
    }
    return result;
}
Wenn wir das Ergebnis der Methode ausdrucken System.out.println(getPlanetAtmosphere(3)), dann wird unser Heimatplanet nicht so geeignet für Leben sein. Oder geeignet? Urteilen Sie selbst: [Kohlendioxid, Stickstoff, Sauerstoff, Wasserstoff, Helium, Methan, Wasserstoff, Helium], Warum ist das passiert? Das Programm führte alle Fälle nach dem ersten Match und bis zum Ende des Switch-Blocks aus.

Übermäßige Optimierungspause

Beachten Sie, dass wir die Methode durch eine andere Anordnung von Break- Anweisungen und Auswahloptionen verbessern können
public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add(„Keine Atmosphäre“);
                break;
        case 3: result.add("Stickstoff");
                result.add("Sauerstoff");
        case 2:
        case 4: result.add("Kohlendioxid");
                break;
        case 7:
        case 8: result.add("Methan");
        case 5:
        case 6: result.add("Wasserstoff");
                result.add("Helium");
    }
     return result;
}
Sieht kürzer aus, oder? Wir haben die Gesamtzahl der Aussagen reduziert, indem wir mit der Fallreihenfolge und Neugruppierung gespielt haben. Jetzt wird jede Gasart in nur einer Codezeile zur Liste hinzugefügt. Die Auflistung des letzten Beispiels der Methode dient nur zur Veranschaulichung der Arbeit; es wird dringend davon abgeraten, in einem solchen Stil zu schreiben. Wenn der Autor (und vor allem Drittprogrammierer) ähnlichen Codes diesen pflegen muss, wird es sehr schwierig sein, die Logik für die Bildung von Auswahlblöcken und ausführbaren Codes für die Java-Switch-Anweisung wiederherzustellen.

Unterschiede zu if

Obwohl die if- und switch- Anweisungen im Aussehen ähnlich sind , vergessen Sie nicht, dass der Multiple-Choice-Operator switch die Auswahl der Ausführungsoptionen auf einem BESTIMMTEN WERT basiert, während in if. kann jeder logische Ausdruck sein. Berücksichtigen Sie diese Tatsache beim Entwerfen Ihres Codes. Schauen wir uns die Neuerungen für den Switch in verschiedenen Java-Versionen genauer an.

Wechseln Sie in Java 7

Vor Java 7 konnten Byte-, Short-, Char- und Int-Primitive als Wert für einen Schalter verwendet werden. Es gab auch Unterstützung für Enum und Wrapper der oben aufgeführten primitiven Typen: Character, Byte, Short und Integer. Aber oft müssen wir den Wert einer Java-Switch-Zeichenfolge finden! So würde es in Java 6 aussehen:
DayOfWeek day = DayOfWeek.fromValue("Thursday");

switch (day) {
  case MONDAY:
     System.out.println("Today is windy !");
     break;
  case THURSDAY:
     System.out.println("Today is sunny !");
     break;
  case WEDNESDAY:
     System.out.println("Today is rainy!");
     break;
  default:
     System.out.println("Oooops, something wrong !");
Und Aufzählung:
public enum DayOfWeek {
  MONDAY("Monday"),
  THURSDAY("Thursday"),
  WEDNESDAY("Wednesday"),
  NOT_FOUND("Not found");

  private final String value;

  DayOfWeek(final String value) {
     this.value = value;
  }

  public static DayOfWeek fromValue(String value) {
     for (final DayOfWeek dayOfWeek : values()) {
        if (dayOfWeek.value.equalsIgnoreCase(value)) {
           return dayOfWeek;
        }
     }
     return NOT_FOUND;
  }
}
Aber ab Java 7 war es möglich, den String-Typ als Wert für einen Schalter zu verwenden:
String day = "Thursday";

switch (day) {
  case "Monday":
     System.out.println("Today is windy !");
     break;
  case "Thursday":
     System.out.println("Today is sunny !");
     break;
  case "Wednesday":
     System.out.println("Today is rainy!");
     break;
  default:
     System.out.println("Oooops, something wrong !");
}
Trotz der neuen Funktionen ist der Ansatz mit enum flexibler und wird zur Verwendung empfohlen: Wir können dieses enum viele Male wiederverwenden.

Wechseln Sie in Java 12

Java 12 hat Switch-Ausdrücke für den Mustervergleich verbessert. Wenn wir Switch wie im obigen Beispiel verwenden, um den Wert einer Variablen festzulegen, müssen wir den Wert berechnen und ihn der angegebenen Variablen zuweisen und dann break verwenden:
int count = 2;
int value;
switch (count) {
  case 1:
     value = 12;
     break;
  case 2:
     value = 32;
     break;
  case 3:
     value = 52;
     break;
  default:
     value = 0;
}
Aber dank der Fähigkeiten von Java 12 können wir diesen Ausdruck wie folgt umschreiben:
int value = switch (count) {
  case 1:
     break 12;
  case 2:
     break 32;
  case 3:
     break 52;
  default:
     break 0;
};
Gehen wir die Änderungen noch einmal kurz durch:
  1. Wenn wir zuvor einen Variablenwert innerhalb von Case-Blöcken festgelegt haben, da die Switch-Anweisung selbst nichts zurückgeben konnte, haben wir jetzt eine solche Möglichkeit und geben den Wert direkt mit Switch zurück.

  2. Früher konnten wir rechts von break nichts mehr haben, aber jetzt verwenden wir es als Return-Anweisung, um den Wert unseres Schalters zurückzugeben. Doppelpunkte markieren den Einstiegspunkt in einen Anweisungsblock. Das heißt, ab diesem Punkt beginnt die Ausführung des gesamten folgenden Codes, auch wenn ein anderes Label angetroffen wird.

    Das Ergebnis ist ein Ende-zu-Ende-Übergang von Marke zu Marke, der auch Fall -Through genannt wird.

Switch-Anweisung in Java - 2Um einen solchen Durchgang abzuschließen, müssen Sie entweder alle Elemente vollständig durchlaufen oder break oder return verwenden. Die Neuerung in Java 12 gibt uns die Möglichkeit, den Lambda-Operator zu verwenden, der wiederum dafür sorgt, dass nur der Code rechts davon ausgeführt wird. Ohne „Misserfolg“. Wie sieht das vorherige Beispiel in diesem Fall aus:
int count = 2;
int value = switch (count) {
  case 1 -> 12;
  case 2 -> 32;
  case 3 -> 52;
  default -> 0;
};
Der Code ist viel einfacher geworden, oder? Und noch etwas: Der Lambda-Operator kann auch als typisches Analogon eines Doppelpunkts dienen, nach dem ein ganzer Block mit einigen Operationen folgt:
int count = 2;
int value = switch (count) {
  case 1 -> {
     //einige Rechenoperationen...
     break 12;
  }
  case 2 -> {
     //einige Rechenoperationen...
     break 32;
  }
  case 3 -> {
     //einige Rechenoperationen...
     break 52;
  }
  default -> {
     //einige Rechenoperationen...
     break 0;
  }
};
Was ist, wenn in einigen Fällen der Rückgabewert derselbe ist? Es stellt sich heraus, dass wir tatsächlich die gleichen Fälle für einige unterschiedliche Werte haben. So könnte dies mithilfe neuer Funktionen in Java 12 verkürzt werden:
int count = 2;
int value = switch (count) {
  case 1, 3, 5 -> 12;
  case 2, 4, 6 -> 52;
  default -> 0;
};

Wechseln Sie in Java 13

In Java 13 hat sich die Art und Weise geändert, wie ein Schalter einen Wert zurückgibt. Wenn wir in Java 12 den Rückgabewert nach Pause geschrieben haben, der uns als Rückgabe für den Switch-Block diente, geben wir den Wert jetzt mit dem Wort yield zurück . Lass uns nachsehen:
int value = switch (count) {
  case 1:
     yield 12;
  case 2:
     yield 32;
  case 3:
     yield 52;
  default:
     yield 0;
};
Gleichzeitig wird in Java 12 geschriebener Code, der Break zum Zurückgeben verwendet, nicht kompiliert (( Switch-Anweisung in Java - 3Break wird verwendet, aber in Situationen, in denen wir nichts zurückgeben müssen.

Gesamt

  • Verwenden Sie die case- Anweisung , wenn mehr als zwei Zweige vorhanden sind, um zu vermeiden, dass Ihr Code mit if-Strukturen überladen wird.
  • Vergessen Sie nicht, den logischen Block jedes Zweigs, der einem bestimmten Wert (Case-Block) entspricht, mit einem Break- Aufruf zu beenden .
  • Zusätzlich zu einigen primitiven Typen kann die Switch-Anweisung auch die Typen Enum und String als Ausdrücke verwenden .
  • Denken Sie an den Standardblock – verwenden Sie ihn, um ungeplante Auswahlwerte zu verarbeiten.
  • Um die Leistung zu optimieren, verschieben Sie die Codezweige mit den häufigsten Auswahlmöglichkeiten an den Anfang des Switch-Blocks.
  • Lassen Sie sich nicht von der „Optimierung“ mitreißen, indem Sie die Unterbrechung am Ende des Fallauswahlblocks entfernen – ein solcher Code ist schwer zu verstehen und daher während seiner Entwicklung schwer zu warten.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION