Verschachtelte If-Else Schleife

laxla123

Mitglied
Java:
import java.util.Scanner;

public class Ü3 {
    
    public static void main(String[] args) {
    
    Scanner scanner    = new Scanner(System.in);
    
    int age;
    
    System.out.println("Gebe dein Alter an: ");
    age = scanner.nextInt();
    
    if(age >= 18); {
        System.out.println("Du bist strafmündig!");
    }if (age >= 14); {
        System.out.println("Du bist bedingt strafmündig!");   
    }else {
        System.out.println("Du bist nicht starfmündig");
    }
    
        
        
        
        
        
    }
}




Bekomme eine FeherMeldung beim else auf Zeile 18. Ist meine Verschachtelung sinnvoll? Es soll 0-14 nicht strafmündig, 14-18 bedingt strafmündig und ab 18 strafmündig sein.
 
nur in eclipse steht da leider immer nur syntax error
Das stimmt wohl. 🙂 Eclipse denkt, dass der Fehler woanders ist und wo es Recht hat, hat es Recht. Wenn du in deinem originalen Code das "else" einfach löschst, dann kompiliert alles wunderbar, ist aber natürlich nicht das, was du eigentlich haben wolltest.
1670015059461.png
By the way: In Eclipse ist es immer eine gute Idee, den Code auch autoformatieren zu lassen. Ab und zu solltest du mal Ctrl+Shift+F drücken, dann erkennt man meist das eigentliche Problem besser.
 
Das stimmt wohl. 🙂 Eclipse denkt, dass der Fehler woanders ist und wo es Recht hat, hat es Recht. Wenn du in deinem originalen Code das "else" einfach löschst, dann kompiliert alles wunderbar, ist aber natürlich nicht das, was du eigentlich haben wolltest.
Anhang anzeigen 19807
By the way: In Eclipse ist es immer eine gute Idee, den Code auch autoformatieren zu lassen. Ab und zu solltest du mal Ctrl+Shift+F drücken, dann erkennt man meist das eigentliche Problem besser.
danke für den tipp 🙂
 
In Zukunft die Fehlerbeschreibung auch in den Thread packen.

If else ist keine Schleife
In der ersten If ist auch schon das Semikolon gesetzt worden.
Wenn man den Scanner nicht mehr braucht, bitte auch die Close Methode aufrufen.
Bitte verwende den Imperativ, anstatt gebe heißt es gib.
Rechtschreibfehler im else Statement.
Was passiert eigentlich wenn du die Zahl 18 eingibst!?
 
Und um auch noch den Grund für das Problem zu erläutern. Die if-Bedingung ist folgendermaßen aufgebaut:

if (Bedingung) Anweisung;

Die Anweisung kann entweder eine einzelne, durch ein Semikolon abgeschlossene Anweisung, sein oder eine Anweisungsblock innerhalb von geschweiften Klammern.

if (Bedingung) { Anweisungsblock }

Durch das Semikolon unmittelbar nach der Bedingung beendest du die if-Bedingung ohne eine Anweisung. Der nachfolgende Anweisungsblock in den geschweiften Klammern steht einfach für sich und wird immer ausgeführt.
 
In Zukunft die Fehlerbeschreibung auch in den Thread packen.

If else ist keine Schleife
In der ersten If ist auch schon das Semikolon gesetzt worden.
Wenn man den Scanner nicht mehr braucht, bitte auch die Close Methode aufrufen.
Bitte verwende den Imperativ, anstatt gebe heißt es gib.
Rechtschreibfehler im else Statement.
Was passiert eigentlich wenn du die Zahl 18 eingibst!?
Wenn ich 18 angebe, dann gibt die Konsole "Du bist strafmündig!" aus
 
Mir ist hierzu gerade etwas eingefallen, vielleicht mag der Ansatz interessant sein:

Java:
import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class Ue3 {
    private static SortedMap<Integer, String> strafmuendigkeit = new TreeMap<>();

    static {
        strafmuendigkeit.put(13, "Schuldunfähig");
        strafmuendigkeit.put(17, "Teilweise schuldfähig");
        strafmuendigkeit.put(99, "Potentiell voll schuldfähig");
        strafmuendigkeit.put(156, "schon sehr klapprig");
    }

    public static void compute() {
        System.out.println("Alter des Angeklagten: ");
        int a = new Scanner(System.in).nextInt();
        System.out.println("Er/sie/es ist: " + strafmuendigkeit.tailMap(a).values().stream().findFirst().orElse("Alter ungültig"));
    }

    public static void main(String[] args) {
        compute();
        compute();
    }
}
 
Mir ist hierzu gerade etwas eingefallen, vielleicht mag der Ansatz interessant sein:

Java:
import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;

public class Ue3 {
    private static SortedMap<Integer, String> strafmuendigkeit = new TreeMap<>();

    static {
        strafmuendigkeit.put(13, "Schuldunfähig");
        strafmuendigkeit.put(17, "Teilweise schuldfähig");
        strafmuendigkeit.put(99, "Potentiell voll schuldfähig");
        strafmuendigkeit.put(156, "schon sehr klapprig");
    }

    public static void compute() {
        System.out.println("Alter des Angeklagten: ");
        int a = new Scanner(System.in).nextInt();
        System.out.println("Er/sie/es ist: " + strafmuendigkeit.tailMap(a).values().stream().findFirst().orElse("Alter ungültig"));
    }

    public static void main(String[] args) {
        compute();
        compute();
    }
}
Er braucht Vergleiche, ein achtzehnjähriger hat den selben Status wie ein siebzehnjähriger. Ein ungültiges Alter gibt's nicht.
Aber man kann natürlich auch mit einer sortierten Map und einer Schleife arbeiten (ich würde übrigens einfach eine Liste von Map.Entry erstellen oder einem passenden record, die Map finde ich etwas overkill), wenn der Nutzen auch bescheiden ist.

Auch möglich wäre natürlich, das Ganze mit einem enum zu lösen.
(Vertipper sind möglich, das ist nur mal schnell hingeklatscht)
Java:
enum RechtsStatus {
    Legende(0,"noch nicht geboren")
    Schuldfaehig(156, "..""),
    TeilweiseSchuldfaehig(17, "..."),
    WahrscheinlichTot(Integer.POSITIVE_INFINITY,"Luegner")

    private Rechtsstatus(int maxAlter, String beschreibung) {
        ...
    }
    public Rechtsstatus getRechtsStatus(int alter) {
        var list = new ArrayList<>(Ararys.asList(Rechtsstatus.values()));
        //Aufsteigend sortieren, was man weglassen kann, wenn die Werte schon in der richtigen Reihenfolge vorliegen
        Collections.sort(list, (o1.o2) -> Integer.compare(o1.getMaxAlter(),o2.getMaxAlter()));
        //Jetzt noch die Schleife
        for (var e : list) {
            if (e.getMaxAlter() >= beschreibung) {
                return e;
            }
        }
    }
}

Wirkt auf den ersten Blick wohl etwas aufgeblasen. Der Vorteil ist, dass man danach einen lesbaren Wert hat, mit der man noch was anfangen kann anstatt nur einem Beschreibungstext.
 
Zuletzt bearbeitet:
Er braucht Vergleiche, ein achtzehnjähriger hat den selben Status wie ein siebzehnjähriger.
Die SortedMap solltest Du Dir einmal ansehen. Das, was er da macht, funktioniert wirklich. Hintergrund ist das tailMap:
Returns a view of the portion of this map whose keys are greater than or equal to fromKey. The returned map is backed by this map, so changes in the returned map are reflected in this map, and vice-versa. The returned map supports all optional map operations that this map supports.
The returned map will throw an IllegalArgumentException on an attempt to insert a key outside its range.

Das values().stream().findFirst() ist einfach nur das Holen des ersten Wertes.

Die Vergleiche macht also die TreeMap beim tailMap Aufruf.

Das ist - ebenso wie die Stream Lösung - eine Spezialität dieses bekannten Users.

Eine Diskussion, in wie weit so ein Beitrag für jemanden hilfreich ist, der gerade einmal if / else lernt, erspare ich uns, zumal die Gefahr besteht, dass die Diskussion dann wieder entgleist (Ebenso eine Code Analyse. Magic Numbers, die alle um 1 kleiner sind als die Zahlen, die erwartet würden ... Aber ich starte schon etwas, das ich nicht starten will ...).
 
@Neumi5694 Bitte lies es so:

Bis einschließlich 13 bist du schuldunfähig.
Bis einschließlich 17 bist du teilweise schuldfähig.
Usw.

@KonradN s Beschreibung ist genau richtig. Die "Magie" geschieht in der "tailMap"-Methode. Diese erlaubt es, viele "if-else if-else"-Kaskaden zu ersetzten - und läuft (imho) in O(1) oder O(log n) (ist also bei mehreren/vielen Kategorien wahnsinnig schnell). Das liegt wieder an der Natur der SortedMap.

Unabhängig davon muss man @KonradN natürlich zustimmen, dass das nur als eine zusätzliche Lösung betrachtet werden soll. Also quasi etwas für später, wenn er oder sie schon weiter ist.

BTW: Auch im Alter von 0 Jahren hat ein Baby schon Rechte.

Dass ich ab 100 Jahren "du bist klapprig" geschrieben haben, sollte nur ein Scherz sein. Lus respicit aequitatem.
 
@KonradN s Beschreibung ist genau richtig. Die "Magie" geschieht in der "tailMap"-Methode. Diese erlaubt es, viele "if-else if-else"-Kaskaden zu ersetzten - und läuft (imho) in O(1) oder O(log n) (ist also bei mehreren/vielen Kategorien wahnsinnig schnell). Das liegt wieder an der Natur der SortedMap.
Genau das habe ich doch Neumi erklärt.

Und wenn man das jetzt doch weiter treibt: Schau Dir einmal die Methoden der TreeMap an: Statt dem Stream Unsinn kann man einfach ceilingEntry nutzen (in Deinem Fall) oder wenn man die Anfangsalter haben will, dann wäre es floorEntry.

Edit: "wenn man die Anfangsalter haben will" hiess: In der TreeMap die Anfangspunkte speichern: 0, 14, 18, ...
 
Zuletzt bearbeitet:
Wieder was gelernt, tailMap kannte ich so nicht. Dann nehm ich alles zurück 🙂
Wobei bei der TreeMap eher die Methoden ceilingEntry bzw. floorEntry wichtig sind. Wenn man mit Interfaces arbeiten will, dann wäre dies nicht SortedMap sondern NavigableMap.

Nicht dass Du auch zu irgendwelchen Streams kommst obwohl es doch schon direkt Methoden gibt, die das gesuchte Element zurück geben 🙂
 
SortedMap hat im Zweifel eine bessere Performance. Deshalb würde ich an der Stelle nicht gegen das höchstmögliche Interface programmieren wollen.

Nicht 0 eintragen, sondern -1 als Alter. Mit der Geburt hat ein Mensch auch schon Rechte (hinsichtlich Unversehrtheit usw.).

Ich hatte das offen gelassen, weil es eine Frage der Religion, Politik und Ethik ist, ob, und wenn ja, ab wann, ein Embryo oder Fötus auch Rechte hat. Da geht es um die Diskussion von Abtreibungen, die überwiegend verbittert in den USA herrscht. Aber damit schweifen wir vom Thema ab. Hardliner sagen, ab der Befruchtung der Eizelle müsse das Leben geschützt werden.

Es ist richtig, die Methoden ceilingEntry bzw. floorEntry direkt zu nutzen. Ich hatte nur nicht gleich daran gedacht.

😵 Passt auf, dass der Krampus euch nicht besucht... 😀
 
SortedMap hat im Zweifel eine bessere Performance.
??? Du redest über Interfaces! Da ist dann ja erst einmal keine Implementierung dahinter. Und egal, welches Interface zu wählst: Du hast eine konkrete Implementierung: TreeMap.

Und erwartest Du tatsächlich, dass es schneller ist, alle Elemente größer (oder kleiner) als ein bestimmten Wert zurück zu geben statt eben das erste Element von der gegebenen Grenze? Denn darum geht es ja gerade in dieser Implementierung.

Daher kann ich Deiner Ausführung erst einmal nicht folgen. Und natürlich nimmt man das Interface, das man benötigt. Nach Deiner Logik hättest Du ansonsten auf das Interface Map setzen müssen.

Nicht 0 eintragen, sondern -1 als Alter. Mit der Geburt hat ein Mensch auch schon Rechte (hinsichtlich Unversehrtheit usw.).
Gut, dass Du hier selbst merkst, wie schlecht die Wahl ist mit der Art, es so einzutragen.
Wenn die Anfangswerte genommen werden und dann mit floorEntry gearbeitet wird, dann sind da natürlich 0, 14, 18, ... einzutragen.

Also die Lösung wäre dann so:
Java:
import java.util.NavigableMap;
import java.util.Scanner;
import java.util.TreeMap;

public class Ue3 {
    private static NavigableMap<Integer, String> strafmuendigkeit = new TreeMap<>();

    static {
//        strafmuendigkeit.put(Integer.MIN_VALUE, "nicht geboren!");
        strafmuendigkeit.put(0, "Schuldunfähig");
        strafmuendigkeit.put(14, "Teilweise schuldfähig");
        strafmuendigkeit.put(18, "Potentiell voll schuldfähig");
        strafmuendigkeit.put(100, "schon sehr klapprig");
    }

    public static void compute() {
        System.out.println("Alter des Angeklagten: ");
        int alter = new Scanner(System.in).nextInt();
        System.out.println("Er/sie/es ist: " + strafmuendigkeit.floorEntry(alter).getValue());
    }

    public static void main(String[] args) {
        compute();
    }
}
 
Gut, anders formuliert: Nicht alle das Interface NavigableMap implementierende Klassen haben dieselbe Laufzeitkomplexität bei bestimmten Operationen, nehme ich an. 🙂
Was aber doch egal ist. Das ist ja wie bei einer List. Die nutzt man ja auch, auch wenn LinkedList eine schlechte Performance hat bezüglich Zugriff auf einen bestimmten index. Das ist ja kein Grund, das Interface List nicht zu nutzen um statt dessen Iterable zu nutzen.

Und das ist auch schlicht irrelevant - denn Du nutzt ja eine spezifische Implementation: TreeMap. Und diese ist im aktuellen Code nicht einmal ersetzbar.

Und in diesem konkreten Fall bezweifle ich, dass bei einer Operation die Laufzeitkomplexität von tailMap besser sein kann als die von ceilingEntry. Denn tailMap liefert das Ergebnis von ceilingEntry + allen weiteren Elementen, dessen Key größer ist.

Das müssen wir aber nicht weiter vertiefen.
 
Na ja, das könnten wir, aber dann sind wir schnell bei Implementierungsdetails der virtuellen Maschine...

Aber nur so viel: Ich nehme an, dass da lediglich flache Kopien zurückgegeben werden. 🙂 So steht es zumindest in der Doku.

Nichtsdestotrotz: Besser die entsprechenden Methoden direkt aufrufen.
 
Java:
import java.util.NavigableMap;
import java.util.Scanner;
import java.util.TreeMap;

public class Ue3 {
    private static NavigableMap<Integer, String> strafmuendigkeit = new TreeMap<>();

    static {
        strafmuendigkeit.put(0, "Schuldunfähig");
        strafmuendigkeit.put(14, "Teilweise schuldfähig");
        strafmuendigkeit.put(18, "Potentiell voll schuldfähig");
        strafmuendigkeit.put(100, "schon sehr klapprig");
    }

    public static void compute() {
        System.out.println("Alter des Angeklagten: ");
        int alter = new Scanner(System.in).nextInt();

        Map.Entry<Integer, String> entry = strafmuendigkeit.floorEntry(alter);
        if (entry == null) {
            System.out.println("Er/sie/es ist noch nicht geboren!");
        } else {
            System.out.println("Er/sie/es ist: " + entry.getValue());
        }
    }

    public static void main(String[] args) {
        compute();
    }
}
 

Neue Themen


Zurück
Oben