Part 1

Bedingte Anweisungen und optionale Operationen

Unsere Programme waren bisher linear. Mit anderen Worten, die Programme wurden von oben nach unten ohne größere Überraschungen oder bedingtes Verhalten ausgeführt. In der Regel möchten Sie jedoch bedingte Logik zu Ihren Programmen hinzufügen. Damit meinen wir Funktionalität, die in irgendeiner Weise vom Zustand der Variablen des Programms abhängt.

Um den Ablauf eines Programms basierend auf Benutzereingaben zu verzweigen, müssen Sie etwas verwenden, das als bedingte Anweisung bekannt ist. Die einfachste bedingte Anweisung sieht folgendermaßen aus:

System.out.println("Hello, World!");
if (true) {
    System.out.println("This code is inevitable!");
}
Beispielausgabe

Hello, World! This code is inevitable!

Eine bedingte Anweisung beginnt mit dem Schlüsselwort if, gefolgt von Klammern. In die Klammern wird ein Ausdruck gesetzt, der ausgewertet wird, wenn die bedingte Anweisung erreicht wird. Das Ergebnis der Auswertung ist ein boolescher Wert. Oben fand keine Auswertung statt. Stattdessen wurde ein boolescher Wert explizit in der bedingten Anweisung verwendet.

Den Klammern folgt ein Block, der innerhalb der geschweiften Klammern { und } definiert ist. Der Quellcode innerhalb des Blocks wird ausgeführt, wenn der Ausdruck innerhalb der Klammern als wahr bewertet wird.

Schauen wir uns ein Beispiel an, bei dem wir Zahlen in der bedingten Anweisung vergleichen.

int number = 11;
if (number > 10) {
    System.out.println("The number was greater than 10");
}

Wenn der Ausdruck in der bedingten Anweisung als wahr bewertet wird, geht die Ausführung des Programms zu dem Block über, der von der bedingten Anweisung definiert wird. Im obigen Beispiel lautet die Bedingung "wenn die Zahl in der Variable größer als 10 ist". Andernfalls, wenn der Ausdruck als falsch bewertet wird, geht die Ausführung zur Anweisung nach der schließenden geschweiften Klammer der aktuellen bedingten Anweisung über.

NB! Eine if-Anweisung wird nicht durch ein Semikolon abgeschlossen, da die Anweisung nach der Bedingung nicht endet.

Loading

Code-Einrückung und Blockanweisungen

Ein Codeblock bezieht sich auf einen Abschnitt, der von einem Paar geschweifter Klammern umschlossen ist. Die Quelldatei, die das Programm enthält, enthält den String public class, gefolgt vom Namen des Programms und der öffnenden geschweiften Klammer des Blocks. Der Block endet mit einer schließenden geschweiften Klammer. Im Bild unten ist der Programmblock hervorgehoben.

Das wiederkehrende Snippet public static void main(String[] args) in den Programmen beginnt einen Block, und der Quellcode darin wird ausgeführt, wenn das Programm gestartet wird - dieses Snippet ist tatsächlich der Ausgangspunkt aller Programme. Wir haben tatsächlich zwei Blöcke im obigen Beispiel, wie auf dem Bild unten zu sehen ist.

Blöcke definieren die Struktur und die Grenzen eines Programms. Eine geschweifte Klammer muss immer ein passendes Paar haben: Jeder Code, dem eine schließende (oder öffnende) geschweifte Klammer fehlt, ist fehlerhaft.

Eine bedingte Anweisung markiert auch den Beginn eines neuen Codeblocks.

Neben der Definition der Programmstruktur und -funktionalität haben Blockanweisungen auch Einfluss auf die Lesbarkeit eines Programms. Code, der sich innerhalb eines Blocks befindet, ist eingerückt. Beispielsweise ist jeder Quellcode innerhalb des Blocks einer bedingten Anweisung vier Leerzeichen tiefer eingerückt als der if-Befehl, der die bedingte Anweisung gestartet hat.Sie können auch durch Drücken der Tabulatortaste (die Taste links neben 'q') Ihren Code einrücken. Wenn der Block endet, d. h. wenn Sie auf ein }-Zeichen stoßen, endet auch die Einrückung. Das }-Zeichen befindet sich auf derselben Einrückungsebene wie der if-Befehl, der die bedingte Anweisung gestartet hat.

Das folgende Beispiel ist falsch eingerückt.

if (number > 10) {
number = 9;
}

Das folgende Beispiel ist korrekt eingerückt.

if (number > 10) {
    number = 9;
}

In Java sind "Fehler", die durch falsches Einrücken, oder durch die evtl. Vermischung von Einrücken mit Tabulator und Einrücken mit Leerzeichen keine syntaktischen Fehler, sondern machen "nur" Ihren Code unleserlich. Andere Programmiersprachen (wie z.B. Python) sind da viel strikter. IDEs wie auch IntelliJ IDEA erlauben die Re-Formatierung Ihres Java-Codes - nutzen Sie diese Möglichkeit um Ihren Code leserlich zu halten:

Loading

Vergleichsoperatoren

  • > größer als
  • >= größer als oder gleich
  • < kleiner als
  • <= kleiner als oder gleich
  • == gleich
  • != ungleich
int number = 55;

if (number != 0) {
    System.out.println("The number is not 0");
}

if (number >= 1000) {
    System.out.println("The number is at least 1000");
}
Beispielausgabe

The number was not 0

Loading
Loading

else

Wenn der Ausdruck innerhalb der Klammern der bedingten Anweisung als falsch bewertet wird, geht die Ausführung des Codes zur Anweisung nach der schließenden geschweiften Klammer der aktuellen bedingten Anweisung über. Dies ist nicht immer erwünscht, und in der Regel möchten Sie eine alternative Option erstellen, wenn der bedingte Ausdruck als falsch bewertet wird.

Dies kann mit Hilfe des else-Befehls erfolgen, der zusammen mit dem if-Befehl verwendet wird.

int number = 4;

if (number > 5) {
    System.out.println("Your number is greater than five!");
} else {
    System.out.println("Your number is five or less!");
}
Beispielausgabe

Your number is five or less!

Wenn für eine bedingte Anweisung ein else-Zweig angegeben wurde, wird der von dem else-Zweig definierte Block ausgeführt, wenn die Bedingung der bedingten Anweisung falsch ist. Der else-Befehl befindet sich in derselben Zeile wie die schließende Klammer des Blocks, der vom if-Befehl definiert wird.

Loading
Loading

Weitere Bedingungen: else if

Im Falle mehrerer Bedingungen verwenden wir den else if-Befehl. Der Befehl else if ist wie else, aber mit einer zusätzlichen Bedingung. else if folgt der if-Bedingung, und es kann mehrere geben.

int number = 3;

if (number == 1) {
    System.out.println("The number is one");
} else if (number == 2) {
    System.out.println("The number is two");
} else if (number == 3) {
    System.out.println("The number must be three!");
} else {
    System.out.println("Something else!");
}
Beispielausgabe

The number must be three!

Lesen wir das obige Beispiel: 'Wenn die Zahl eins ist, dann drucke "The number is one", sonst, wenn die Zahl zwei ist, dann drucke "The number is two", sonst, wenn die Zahl drei ist, dann drucke "The number must be three!". Andernfalls drucke "Something else!"'

Die schrittweise Visualisierung des obigen Codes:

Loading...
Loading

Ausführungsreihenfolge von Vergleichen

Die Vergleiche werden von oben nach unten ausgeführt. Wenn die Ausführung eine bedingte Anweisung erreicht, deren Bedingung wahr ist, wird deren Block ausgeführt und die Vergleiche stoppen.

int number = 5;

if (number == 0) {
    System.out.println("The number is zero.");
} else if (number > 0) {
    System.out.println("The number is greater than zero.");
} else if (number > 2) {
    System.out.println("The number is greater than two.");
} else {
    System.out.println("The number is less than zero.");
}
Beispielausgabe

The number is greater than zero.

Das obige Beispiel druckt den String "The number is greater than zero.", auch wenn die Bedingung number > 2 wahr ist. Der Vergleich stoppt bei der ersten Bedingung, die als wahr bewertet wird.

Loading

Bedingte Anweisungsausdrücke und die boolesche Variable

Der Wert, der zwischen die Klammern der bedingten Anweisung gesetzt wird, sollte nach der Auswertung vom Typ boolean sein. boolean-Variablen sind entweder true oder false.

boolean isTrue = true;
System.out.println("The value of the boolean variable is " + isTrue);
Beispielausgabe

The value of the boolean variable is true

Die bedingte Anweisung kann auch wie folgt erstellt werden:

boolean isTrue = true;
if (isTrue) {
    System.out.println("Pretty wild!");
}
Beispielausgabe

Pretty wild!

Vergleichsoperatoren können auch außerhalb von Bedingungen verwendet werden. In diesen Fällen wird der boolesche Wert, der aus dem Vergleich resultiert, in einer booleschen Variable für die spätere Verwendung gespeichert.

int first = 1;
int second = 3;
boolean isGreater = first > second;

Im obigen Beispiel enthält die boolesche Variable isGreater jetzt den booleschen Wert false. Wir können das vorherige Beispiel erweitern, indem wir eine bedingte Anweisung hinzufügen.

int first = 1;
int second = 3;
boolean isItLessThan = first < second;

if (isItLessThan) {
    System.out.println("1 is smaller than 3!");
}

Der Code im obigen Bild wurde bis zu dem Punkt ausgeführt, an dem die Variablen des Programms erstellt und ihnen Werte zugewiesen wurden. Die Variable isItLessThan hat den Wert true. Als nächstes in der Ausführung steht der Vergleich if (isItLessThan) - der Wert für die Variable isItLessThan wird in ihrem Container gefunden, und das Programm druckt schließlich:

Beispielausgabe

1 is smaller than 3!

Loading

Bedingte Anweisungen und das Vergleichen von Zeichenketten

Auch wenn wir ganze Zahlen, Gleitkommazahlen und boolesche Werte mit zwei Gleichheitszeichen (variable1 == variable2) vergleichen können, können wir die Gleichheit von Zeichenketten nicht mit zwei Gleichheitszeichen vergleichen.

Sie können dies mit dem folgenden Programm ausprobieren:

Scanner reader = new Scanner(System.in);

System.out.println("Give the first string:");
String first = reader.nextLine();
System.out.println("Give the second string:");
String second = reader.nextLine();

if (first == second) {
    System.out.println("The strings were the same!");
} else {
    System.out.println("The strings were different!");
}
Beispielausgabe

Give the first string: same Give the second string: same The strings were different!

Beispielausgabe

Give the first string: same Give the second string: different The strings were different!

Dies hat mit dem internen Aufbau von Zeichenketten und der Implementierung des Variablenvergleichs in Java zu tun, wir werden das später in der Vorlesung detailliert analysieren. Hier eine vereinfachte Erklärung, die ohne Begirffe wie primitive Datentypen und Referenztypen auskommt: Zeichenketten können eine potentiell unbegrenzte Anzahl von Zeichen enthalten, während ganze Zahlen, Gleitkommazahlen und boolesche Werte immer nur eine einzelne Zahl oder einen Wert enthalten. Variablen, die immer nur eine Zahl oder einen Wert enthalten, können mit einem Gleichheitszeichen verglichen werden, während dies bei Variablen, die mehr Informationen enthalten, nicht funktioniert. Wie gesagt, wir werden später in diesem Kurs auf dieses Thema zurückkommen.

Beim Vergleichen von Zeichenketten verwenden wir den equals-Befehl, der mit Zeichenkettenvariablen verbunden ist. Der Befehl funktioniert folgendermaßen:

Scanner reader = new Scanner(System.in);

System.out.println("Give a string:");
String input = reader.nextLine();

if (input.equals("a string")) {
    System.out.println("Great! You followed the instructions correctly.");
} else {
    System.out.println("Missed the mark!");
}
Beispielausgabe

Give a string: ok! Missed the mark!

Beispielausgabe

Give a string: a string Great! You followed the instructions correctly.

Der equals-Befehl wird nach einer Zeichenkette geschrieben, indem er mit einem Punkt an die zu vergleichende Zeichenkette angehängt wird. Der Befehl erhält einen Parameter, der die Zeichenkette ist, mit der die Variable verglichen wird. Wenn die Zeichenkettenvariable direkt mit einer Zeichenkette verglichen wird, kann die Zeichenkette in Anführungszeichen in die Klammern des equals-Befehls gesetzt werden. Andernfalls wird der Name der Zeichenkettenvariable, die die zu vergleichende Zeichenkette enthält, in die Klammern gesetzt.

Im folgenden Beispiel wird der Benutzer nach zwei Zeichenketten gefragt. Zuerst überprüfen wir, ob die bereitgestellten Zeichenketten gleich sind, und dann überprüfen wir, ob der Wert einer der beiden Zeichenketten "two strings" ist.

Scanner reader = new Scanner(System.in);

System.out.println("Give two strings:");
String first = reader.nextLine();
String second = reader.nextLine();

if (first.equals(second)) {
    System.out.println("The strings were the same!");
} else {
    System.out.println("The strings were different!");
}

if (first.equals("two strings")) {
    System.out.println("Clever!");
}

if (second.equals("two strings")) {
    System.out.println("Smart!");
}
Beispielausgabe

Give two strings: hello world The strings were different!

Beispielausgabe

Give two strings: two strings world The strings were different! Clever!

Beispielausgabe

Give two strings: same same The strings were the same!

Loading
Loading

Logische Operatoren

Der Ausdruck einer bedingten Anweisung kann aus mehreren Teilen bestehen, in denen die logischen Operatoren und &&, oder || und nicht ! verwendet werden.

  • Ein Ausdruck, der aus zwei Ausdrücken besteht, die mit dem und-Operator verbunden sind, ist wahr, wenn und nur wenn beide verbundenen Ausdrücke als wahr bewertet werden.

  • Ein Ausdruck, der aus zwei Ausdrücken besteht, die mit dem oder-Operator verbunden sind, ist wahr, wenn einer oder beide der verbundenen Ausdrücke als wahr bewertet werden.

  • Logische Operatoren werden nicht verwendet, um den booleschen Wert von wahr zu falsch oder von falsch zu wahr zu ändern.

Im nächsten Beispiel kombinieren wir zwei einzelne Bedingungen mit &&, also dem und-Operator. Der Code wird verwendet, um zu überprüfen, ob die Zahl in der Variablen größer oder gleich 5 und kleiner oder gleich 10 ist. Mit anderen Worten, ob sie im Bereich von 5-10 liegt:

System.out.println("Is the number in the range 5-10: ");
int number = 7;

if (number >= 5 && number <= 10) {
    System.out.println("Yes! :)");
} else {
    System.out.println("No :(");
}
Beispielausgabe

Is the number in the range 5-10: Yes! :)

Im nächsten Beispiel geben wir zwei Bedingungen mit ||, also dem oder-Operator: Ist die Zahl kleiner als null oder größer als 100. Die Bedingung ist erfüllt, wenn die Zahl eine der beiden Bedingungen erfüllt:

System.out.println("Is the number smaller than 0 or greater than 100");
int number = 145;

if (number < 0 || number > 100) {
    System.out.println("Yes! :)");
} else {
    System.out.println("No :(");
}
Beispielausgabe

Is the number smaller than 0 or greater than 100 Yes! :)

In diesem Beispiel kehren wir das Ergebnis des Ausdrucks number > 4 mit !, also dem nicht-Operator, um. Der nicht-Operator wird so geschrieben, dass der umzukehrende Ausdruck in Klammern gesetzt wird und der nicht-Operator vor die Klammern gesetzt wird.

int number = 7;

if (!(number > 4)) {
    System.out.println("The number is not greater than 4.");
} else {
    System.out.println("The number is greater than 4.");
}
Beispielausgabe

The number is greater than 4.

Im Folgenden ist eine Tabelle dargestellt, die die Funktionsweise von Ausdrücken mit logischen Operatoren zeigt.

numbernumber > 0number < 10number > 0 && number < 10!(number > 0 && number < 10)number > 0 || number < 10
-1falsetruefalsetruetrue
0falsetruefalsetruetrue
1truetruetruefalsetrue
9truetruetruefalsetrue
10truefalsefalsetruetrue
Loading

Ausführungsreihenfolge von bedingten Anweisungen

Lassen Sie uns mit einem klassischen Programmierbeispiel die Ausführungsreihenfolge von bedingten Anweisungen kennenlernen.

'Schreiben Sie ein Programm, das den Benutzer nach einer Zahl zwischen eins und hundert fragt und diese Zahl ausgibt. Wenn die Zahl durch drei teilbar ist, drucken Sie "Fizz" anstelle der Zahl. Wenn die Zahl durch fünf teilbar ist, drucken Sie "Buzz" anstelle der Zahl. Wenn die Zahl sowohl durch drei als auch durch fünf teilbar ist, drucken Sie "FizzBuzz" anstelle der Zahl.'

Der Programmierer beginnt mit der Lösung der Übung, indem er die Übungsbeschreibung liest und Code entsprechend der Beschreibung schreibt. Die Bedingungen für die Ausführung werden in einer bestimmten Reihenfolge von der Beschreibung präsentiert, und die anfängliche Struktur des Programms wird auf dieser Reihenfolge basieren. Die Struktur wird basierend auf den folgenden Schritten gebildet:

  • Schreiben Sie ein Programm, das den Benutzer nach einer Zahl fragt und diese Zahl ausgibt.

  • Wenn die Zahl durch drei teilbar ist, drucken Sie "Fizz" anstelle der Zahl.

  • Wenn die Zahl durch fünf teilbar ist, drucken Sie "Buzz" anstelle der Zahl.

  • Wenn die Zahl sowohl durch drei als auch durch fünf teilbar ist, drucken Sie "FizzBuzz" anstelle der Zahl.

Wenn-Bedingungen sind leicht mit if - else if - else -bedingten Anweisungen zu implementieren. Der untenstehende Code wurde basierend auf den oben genannten Schritten geschrieben, funktioniert jedoch nicht korrekt, wie aus dem Beispiel ersichtlich ist.

Scanner reader = new Scanner(System.in);

int number = Integer.valueOf(reader.nextLine());

if (number % 3 == 0) {
    System.out.println("Fizz");
} else if (number % 5 == 0) {
    System.out.println("Buzz");
} else if (number % 3 == 0 && number % 5 == 0) {
    System.out.println("FizzBuzz");
} else {
    System.out.println(number);
}
Beispielausgabe

3 Fizz

Beispielausgabe

4 4

Beispielausgabe

5 Buzz

Beispielausgabe

15 Fizz

Das Problem beim vorherigen Ansatz ist, dass die Analyse der bedingten Anweisungen bei der ersten Bedingung, die als wahr bewertet wird, gestoppt wird. Zum Beispiel wird bei dem Wert 15 der String "Fizz" ausgegeben, da die Zahl durch drei teilbar ist (15 % 3 == 0).

Ein Ansatz zur Verbesserung dieses Gedankengangs besteht darin, zuerst die anspruchsvollste Bedingung zu finden und sie umzusetzen. Danach würden wir die anderen Bedingungen umsetzen. Im obigen Beispiel erfordert die Bedingung "wenn die Zahl sowohl durch drei als auch durch fünf teilbar ist" das Eintreten von zwei Fällen. Jetzt wäre der Gedankengang folgendermaßen:

  1. Schreiben Sie ein Programm, das Benutzereingaben liest.

  2. Wenn die Zahl sowohl durch drei als auch durch fünf teilbar ist, drucken Sie "FizzBuzz" anstelle der Zahl.

  3. Wenn die Zahl durch drei teilbar ist, drucken Sie "Fizz" anstelle der Zahl.

  4. Wenn die Zahl durch fünf teilbar ist, drucken Sie "Buzz" anstelle der Zahl.

  5. Andernfalls druckt das Programm die vom Benutzer eingegebene Zahl.

Jetzt scheint das Problem gelöst zu sein.

Scanner reader = new Scanner(System.in);

int number = Integer.valueOf(reader.nextLine());

if (number % 3 == 0 && number % 5 == 0) {
    System.out.println("FizzBuzz");
} else if (number % 3 == 0) {
    System.out.println("Fizz");
} else if (number % 5 == 0) {
    System.out.println("Buzz");
} else {
    System.out.println(number);
}
Beispielausgabe

2 2

Beispielausgabe

5 Buzz

Beispielausgabe

30 FizzBuzz

Loading
Loading
Sie haben das Ende dieses Abschnitts erreicht! Weiter zum nächsten Abschnitt: