Mehrfache if-else-Abfrage zusammenfassen

javamin

Mitglied
Guten Abend,
Wie im Titel bereits beschrieben geht meine Frage um das Zusammenfassen von mehrfachen if-else-Abfragen.
Als Programmierumgebung benutzte ich XDEV 6, die Frage bezieht sich allerdings ganz allgemein auf die Programmierung (auch nicht nur Java) und nicht auf XDEV.

Also...
Ich bin gerade dabei mir mittels XDEV eine GUI zu programmieren, in welcher man unter Anderem eine Combobox zur Auswahl hat. Diese Combobox ändert ihren Index mit der Auswahl eines Eintrages. Heißt Ich habe zum Beispiel die Auswahlmöglichkeiten Hund, Katze und Maus. Hund hat den Index 0, Katzte den Index 1 und Maus den Index 2.
Nun frage ich per if-else den Index ab und öffne dadurch dann ein Fenster in einem windowContainer. Bei meinen 6 Auswahlmöglichkeiten wird es allerdings etwas unübersichtlich.
Jetzt meine Frage, ob man das irgendwie zusammenfassen kann (ich stelle mir das ungefähr so wie in der angehängten Datei vor)?

Würde mich über jeden Lösungsansatz freuen auch wenn er vielleicht etwas albern erscheint und hoffe ihr habt meine Frage verstanden 😉
Liebe Grüße
Benjamin



HIER MEIN CODE:

Java:
@EventHandlerDelegate
    void comboBox_itemStateChanged(ItemEvent arg0)
    {
        int selectionComboBox = comboBox.getSelectedIndex();
        
        if(selectionComboBox == 0)
        {
            windowContainer.setXdevWindow(new wndNdG());
        }
        else
        {
            if(selectionComboBox == 1)
            {
                windowContainer.setXdevWindow(new wndNdM());
            }
            else
            {
                if(selectionComboBox == 2)
                {
                    windowContainer.setXdevWindow(new wndNdParameter());
                }
                else
                {
                    if(selectionComboBox == 3)
                    {
                        windowContainer.setXdevWindow(new wndNdAlarm());
                    }
                    else
                    {
                        if(selectionComboBox == 4)
                        {
                            windowContainer.setXdevWindow(new wndNdError());
                        }
                        else
                        {
                            windowContainer.setXdevWindow(new wndNdOther());
                        }
                        
                    }
                    
                }
            }
        }
    }
 

Anhänge

  • Zusammenfassung if-else Beispiel.txt
    517 Bytes · Aufrufe: 0

KonradN

Super-Moderator
Mitarbeiter
a) Wenn Du if / else if / else if / else Konstrukte hast, dann mach beim else if keinen Block. Dann hast Du nicht diese immer tiefere Einrückung.

b) Wenn du bei einer Variable mehrere Werte abfragen willst, dann kannst Du den switch Befehl nutzen.
 

KonradN

Super-Moderator
Mitarbeiter
Ach ja - falls ein switch nicht möglich ist, weil es z.B. nicht um int Werte sondern um Instanzen geht oder so, dann kannst Du auch eine Map verwenden, die Du füllst.

Dann hast Du eine Map mit den Instanzen als Key und Value ist dann eine Methodenreferenz oder so. Also in der Regel etwas aus dem java.util.function Namespace oder ein funktionales Interface.
 

javamin

Mitglied
Hi Konrad,
Erstmal vielen Dank für deine Hilfe!!!
Habe es mit der switch-Methode gelöst und bin sehr zufrieden.

Vielen Dank nochmal und noch einen schönen Abend
Benjamin

PS:
Um anderen den Aufbau einer solchen Methode zu zeigen hier der neue Code:

Java:
    @EventHandlerDelegate
    void comboBox_itemStateChanged(ItemEvent arg0)
    {
        int selectionComboBox = comboBox.getSelectedIndex();
        
        switch(selectionComboBox)
        {
            
            case 1:
            {
                windowContainer.setXdevWindow(new wndNdM());
            }
            break;
            case 2:
            {
                windowContainer.setXdevWindow(new wndNdParameter());
            }
            break;
            case 3:
            {
                windowContainer.setXdevWindow(new wndNdAlarm());
            }
            break;
            case 4:
            {
                windowContainer.setXdevWindow(new wndNdError());
            }
            break;
            case 5:
            {
                windowContainer.setXdevWindow(new wndNdOther());
            }
            break;
        
            default:
            {
                windowContainer.setXdevWindow(new wndNdG());
            }
        }
        
    }
 

KonradN

Super-Moderator
Mitarbeiter
Die Blöcke im case sind eher unüblich. Die mehr übliche Formatierung wäre dann:

Java:
    @EventHandlerDelegate
    void comboBox_itemStateChanged(ItemEvent arg0) {
        int selectionComboBox = comboBox.getSelectedIndex();
       
        switch(selectionComboBox) {
           
            case 1:
                windowContainer.setXdevWindow(new wndNdM());
                break;

            case 2:
                windowContainer.setXdevWindow(new wndNdParameter());
                break;
               
            case 3:
                windowContainer.setXdevWindow(new wndNdAlarm());
                break;
               
            case 4:
                windowContainer.setXdevWindow(new wndNdError());
                break;
               
            case 5:
                windowContainer.setXdevWindow(new wndNdOther());
                break;
       
            default:
                windowContainer.setXdevWindow(new wndNdG());
        }      
    }

Edit: In Java ist es üblich, die öffnenden Klammern am Ende der Zeile zu haben.
 

javamin

Mitglied
Noch besser. Ich dachte nur dass das so gehört, da es wo ich die "Schreibweise" nachgelesen habe so dargestellt wird.
Aber wenn die Klammern nicht zwingend notwendig sind soll's mir sehr recht sein.

Vielen Dank für den Hinweis
 

mihe7

Top Contributor
Mit neueren Java-Versionen:
Java:
        windowContainer.setXdevWindow(switch (selectionComboBox) {
            case 1 -> new wndNdM();
            case 2 -> new wndNdParameter();
            case 3 -> new wndNdAlarm();
            case 4 -> new wndNdError();
            case 5 -> new wndNdOther();
            default -> new wndNdG();
        });
 

philanthrop

Bekanntes Mitglied
Hier noch schnell der Generics Flavor (damit kann man sich die Fallunterscheidung(switch-case) sparen):

Java:
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

public class EncapsulateInstantiation {
    public static class MyClassA {
        public MyClassA() {
            System.out.println("MyClassA was instantiated.");
        }
    }

    public static class MyClassB {
        public MyClassB() {
            System.out.println("MyClassB was instantiated.");
        }
    }

    public static class MyClassC {
        public MyClassC() {
            System.out.println("MyClassC was instantiated.");
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T getInstance(final Class<T> type) throws InvocationTargetException, InstantiationException, IllegalAccessException {
        HashMap<String, Class<?>> map = new HashMap<>();
        map.put(MyClassA.class.getName(), MyClassA.class);
        map.put(MyClassB.class.getName(), MyClassB.class);
        map.put(MyClassC.class.getName(), MyClassC.class);

        Class<?> aClass = map.get(type.getName());
        if (aClass == null) {
            return null;
        }
        return (T) aClass.getConstructors()[0].newInstance(new Object[0]);
    }

    public static void main(final String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException {
        MyClassB myb = getInstance(MyClassB.class);
    }
}

( anstatt Class<T> type könnte man dann einen int-Wert übergeben )
 

philanthrop

Bekanntes Mitglied
Also sprich so:

Java:
    @SuppressWarnings("unchecked")
    public static <T> T getInstance(final int type) throws InvocationTargetException, InstantiationException, IllegalAccessException {
        HashMap<Integer, Class<?>> map = new HashMap<>();
        map.put(1, MyClassA.class);
        map.put(2, MyClassB.class);
        map.put(3, MyClassC.class);

        Class<?> aClass = map.get(type);
        if (aClass == null) {
            return null;
        }
        return (T) aClass.getConstructors()[0].newInstance(new Object[0]);
    }

    public static void main(final String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException {
        MyClassB myb = getInstance(2);
    }

Das @SuppressWarnings("unchecked") kommt durch den Cast in der return Anweisung ... Falls man das nicht möchte, sollte man Object bzw. einen Superklassentyp zurückgeben.
 

KonradN

Super-Moderator
Mitarbeiter
Das mit der Map ist der Weg, den ich in #3 erwähnt hatte. Auch ohne die Methodenreferenz auf den Konstruktor wäre es denkbar, dass über eine Lambda Expression zu machen. Der Ausdruck von @thecain wäre dann z.B, ein map.put(1, () -> new MyClassA());

Und bei dem Code in #9 macht das wenig Sinn:
Java:
        HashMap<String, Class<?>> map = new HashMap<>();
        map.put(MyClassA.class.getName(), MyClassA.class);
        map.put(MyClassB.class.getName(), MyClassB.class);
        map.put(MyClassC.class.getName(), MyClassC.class);

        Class<?> aClass = map.get(type.getName());

Du hast in type bereits die Class<T>. Daher musst Du da nicht erst den Namen holen um dann die Class erneut zu bekommen. Etwas in der Art wäre nur dann sinnvoll, wenn Du da Abweichungen hättest a.la. "List" -> ArrayList.class oder so. Aber da macht dann das Generic keinen Sinn. Ebenso ist bei dem Code mit dem int Wert der Generic nicht wirklich sinnvoll in meinen Augen.

Aber die Map Lösung ist immer dann sinnvoll, wenn ein switch nicht geht (Weil der Typ nicht unterstützt wird oder weil es dynamisch ist und nicht alle Fälle bekannt sind).

Und natürlich steht dann noch die Frage im Raum, was denn da als Typ angegeben wird für den Value der Map. Da kann man dann zum einen bei den vorhandenen Elementen von java.util.function schauen - da wäre dann z.B. Supplier<T> das mit der T get(); Methode ein passendes funktionales Interface ist.
Ansonsten geht jedes funktionales Interface mit entsprechender Methodensignatur. Wenn einem das get() also nicht passt, dann kann man auch etwas bauen wie:
Java:
public interface Factory<T> {
    T create();
}
Dann hat man halt speziell für die Map einen eigenen Typ und es wird dann auch klar bei der Nutzung, denn man hat dann etwas wie: map.get(....).create(); und es wird deutlich, dass eine neue Instanz erzeugt wird und nicht einfach nur eine Instanz zurück gegeben wird. Bei einem get() ist eher die Erwartungshaltung, dass zwei get() Aufrufe hintereinander immer das selbe zurück gibt. Das würde aus meiner Sicht etwas dagegen sprechen.
 

philanthrop

Bekanntes Mitglied
War nur ein Beispiel. #10 ist als Korrektur zu #9 zu verstehen ... Aber wenn du nur public static <T> T getInstance() (bzw. public static <T> T getNewInstance()) hast, dann kommst du nicht an den Typ / an getClass() des Typs heran.

Ob die Methode nun get... oder new... heißt ist fast egal ... Instance deutet an, dass es hier um eine Instanziierung geht. Ich würde getNewInstance fast als doppelt gemoppelt empfinden.

Wie dem auch sei, ...::new ist deutlich angenehmer zu lesen. Es ist aber noch fraglich, ob das auch für alle Fälle funktionieren würde.

Solche Konstrukte hat man relativ selten. Ad hoc fiele mir gar kein (sinnvolles) Anwendungsbeispiel ein.

Das mit der Map ist der Weg, den ich in #3 erwähnt hatte.
Stimmt, da hatte ich halb überlesen, aber ein Beispiel dazu gebracht.
 

philanthrop

Bekanntes Mitglied
Ich hab mal gerade etwas damit herumgespielt ... Es ist doch in allen Fällen möglich, aber es ist teils "abartig", was alles geht:

Java:
import java.util.HashMap;
import java.util.function.Function;
import java.util.function.Supplier;

public class EncapsulateInstantiation {
    public static class MyClassA {
        public MyClassA() {
            System.out.println("MyClassA was instantiated.");
        }
    }

    public static class MyClassB {
        public MyClassB() {
            System.out.println("MyClassB was instantiated.");
        }

        public MyClassB(final String s) {
            System.out.println(s);
        }
    }

    public static class MyClassC {
        public MyClassC() {
            System.out.println("MyClassC was instantiated.");
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T getInstance(final int type, final String dummyString) {
        HashMap<Integer, Supplier<?>> supplierHashMap = new HashMap<>();
        supplierHashMap.put(1, MyClassA::new);
        supplierHashMap.put(2, MyClassB::new);
        supplierHashMap.put(3, MyClassC::new);
        HashMap<Integer, Function<?, ?>> functionHashMap = new HashMap<>();
        functionHashMap.put(4, (Function<String, MyClassB>) MyClassB::new);

        if (type >= 1 && type <= 3) {
            return (T) supplierHashMap.get(type).get();
        } else if (type == 4) {
            return (T) ((Function<String, ?>) functionHashMap.get(type)).apply(dummyString);
        } else {
            return null;
        }
    }

    public static void main(final String[] args) {
        MyClassB myb = getInstance(2, "dummy1");
        System.out.println("myb = " + myb);
        MyClassB myb2 = getInstance(4, "dummy2");
        System.out.println("myb2 = " + myb2);

    }
}

die Ausgabe ist dann tatsächlich:

Code:
MyClassB was instantiated.
myb = EncapsulateInstantiation$MyClassB@5674cd4d
dummy2
myb2 = EncapsulateInstantiation$MyClassB@63961c42
 

javamin

Mitglied
Vielen vielen Dank erstmal für eure rege Beteiligung!!!
Aufgrund meiner erst als Grundlagen existierenden Java-Fähigkeiten benutzte ich jetzt die switch-case Methode, da #8 bei mir nicht funktioniert ( "->" wird rot unterstrichen und er scheibt "Syntax error on token "->", : expected" ... soll ich einen Doppelpunkt irgendwo einfügen?) und ich das mit der HashMap nicht verstanden habe. Ist diese insgesamt nicht etwas zu "schlau" für meine Aufgabe? Und dann etwas viel länger als switch-case?
 

philanthrop

Bekanntes Mitglied
Ist diese insgesamt nicht etwas zu "schlau" für meine Aufgabe? Und dann etwas viel länger als switch-case?
Eine Fallunterscheidung benötigt immer eine gewisse Zeit... Bei 5 Fällen ist das absolut vernachlässigbar (und sogar schneller ), aber wenn es jetzt 5 Millionen Fälle gäbe, dann ist eine "dynamische" Herangehensweise besser.

Das bedeutet, mach dir um die map-Sachen erst einmal noch keinen Kopf ...
 

javamin

Mitglied
Habe jetzt in XDEV das JDK eingebunden und einfach nur ein neues GUI-Fenster erstellt und es kommt folgende Meldung, wenn ich mit dem Cursor über den rot unterstrichenen Text streiche (Anhang).
Wenn ich das JRE aktiviere funktioniert alles reibungslos.
 

Anhänge

  • Screenshot 2023-09-16 101212.png
    Screenshot 2023-09-16 101212.png
    21,3 KB · Aufrufe: 0
  • Screenshot 2023-09-16 101240.png
    Screenshot 2023-09-16 101240.png
    26,5 KB · Aufrufe: 0

javamin

Mitglied
Habe es jetzt installiert und es geht immer noch nicht als Anhang die Informationsdatei des JDKs.
Habe ich das richtige installiert?
 

Anhänge

  • release.txt
    1,3 KB · Aufrufe: 0

javamin

Mitglied
Gebe ich dort einfach den jdk-17 ordner an oder eine bestimmte Datei? Wie ich das bei dir sehe den bin-Ordner?
 
Zuletzt bearbeitet:

javamin

Mitglied
Bitte Verzeihe mir meine aktuelle Kurzsichtigkeit 😕
aber bei Path sind neben meinem ...\bin viele andere Pfade. Egal?
und Java_Home existiert nicht. Soll ich es neu erstellen?
 

javamin

Mitglied
Wobei wir uns jetzt rein in Xdev bewegen und nicht mehr in Java. Ich frage vielleicht lieber mal in einem Xdev-Forum, da das hier auch schon längst nichts mehr mit dem Thread Titel zutun hat...
 

javamin

Mitglied
Ja, das ist schon mal gut... Jetzt musst du diese Einstellungen nur noch für das aktuelle Projekt anwenden oder ein neues erstellen...
Nach wie vor #22

Ich versuche es mal woanders.
Trotzdem vielen vielen Dank dir und auch euch anderen für eure außerordentlich schnelle,hilfreiche und vor allem NETTE (ist nicht in allen Foren selbstverständlich...leider) Hilfe
Liebe Grüße und ein schönes Wochenende noch
Benjamin
 

M.L.

Top Contributor
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Mehrfache XOR Verschlüsselung Allgemeine Java-Themen 11
S OOP Mehrfache Vererbung von abstrakten Klassen Allgemeine Java-Themen 7
Daniel_L Mehrfache Ausführung desselben Threads/Tasks verhindern? Allgemeine Java-Themen 4
ReinerCoder Case statt if else Abfragen?! Allgemeine Java-Themen 8
M Variablen If - Else Wiederholungsfehler Allgemeine Java-Themen 3
L Vererbung If-Else ersetzen durch was? Allgemeine Java-Themen 20
O Darstellung von else if anweisung im struktogramm? Allgemeine Java-Themen 1
R Wie schaffe ich es, dass java zB 100 zählt ohne ständig "else if" hinschreiben zu müssen? Allgemeine Java-Themen 7
J if else Anweisung macht nicht was es soll. Wieso? Allgemeine Java-Themen 10
K Eclipse Alternativkonstrukte (Verzweigungen: if, switch,else..) Allgemeine Java-Themen 4
D if - else Baum vereinfachen Allgemeine Java-Themen 4
S Else-Anweisung Problem Allgemeine Java-Themen 17
B Berechnung von Punkten/ If-else Strategie?! Allgemeine Java-Themen 51
M if - else Abfrage beenden Allgemeine Java-Themen 4
M if, else, etc. als Membervariablen? Allgemeine Java-Themen 14
P if(a) else if (b) else if (c) . Frage Allgemeine Java-Themen 2
G die mittlere von 5 Zahlen nur mit if und else finden Allgemeine Java-Themen 48
U Kompilieren einer großen Datei if-else = StackOverflowError Allgemeine Java-Themen 4
W kompliziertes Konstrukt von Schleifen/If/else. Rekursion? Allgemeine Java-Themen 22
G switch case VS. if.else if Allgemeine Java-Themen 2
H if - else if-else bessere Lösung gesucht Allgemeine Java-Themen 4
H If anweisungen zu verschachtelt? else without if Allgemeine Java-Themen 8
D Performancefrage zu "else if" und "||" Allgemeine Java-Themen 10
G if . else ? Allgemeine Java-Themen 36
B Wie erstelle ich dazu eine Abfrage ob der Button gedrückt wurde? Allgemeine Java-Themen 8
L 2 Dimensionale ListArray Abfrage nach einem Wert suchen Allgemeine Java-Themen 5
I Wie kann ich den Wert aus einer If abfrage ausgeben Allgemeine Java-Themen 23
Zeppi NullPointerException in einer if-Abfrage Allgemeine Java-Themen 6
1Raini Java if-Abfrage funktioniert nicht! Allgemeine Java-Themen 3
tom.j85 Exception bei Abfrage von Ländercodes in API? Allgemeine Java-Themen 13
T Fehler bei IF abfrage Allgemeine Java-Themen 8
D Mehrdimensionale Abfrage Allgemeine Java-Themen 15
MiMa If-Abfrage mit Parameter Allgemeine Java-Themen 8
kodela Binäre Abfrage Allgemeine Java-Themen 12
D MAC Adressen Abfrage Allgemeine Java-Themen 5
J Problem bei Hashmap Key-Abfrage Allgemeine Java-Themen 4
B Swing Hilfe bei Abfrage von Benutzernamen und Passwort Allgemeine Java-Themen 2
J If Abfrage funktioniert nicht Allgemeine Java-Themen 4
B Java Abfrage Netzbetrieb oder Akkubetrieb Allgemeine Java-Themen 1
T Login-Abfrage Allgemeine Java-Themen 3
T Login mit LDAP-Abfrage Allgemeine Java-Themen 3
M Event Handling Tastatur abfrage Allgemeine Java-Themen 5
2 If-Abfrage um Uhrzeit einzuordnen Allgemeine Java-Themen 2
F Java ip abfrage mit Dateiausgabe ? Allgemeine Java-Themen 2
V Java Editor Problem mit ! bei if-Abfrage Allgemeine Java-Themen 5
N Schlüsselworte if abfrage ob linke oder rechte maustaste gedrückt ist Allgemeine Java-Themen 5
H args abfrage vereinfachen Allgemeine Java-Themen 7
P Tastatur abfrage ohne KeyListener Allgemeine Java-Themen 3
E Methoden Server Benutzer abfrage Allgemeine Java-Themen 2
D Internet Abfrage aber mit Warteschleife Allgemeine Java-Themen 6
B Kapselung if-Abfrage bei "MVC-verteilten" Listenern Allgemeine Java-Themen 5
R JNI if abfrage gibt immer false zurück. Allgemeine Java-Themen 7
S if-Abfrage Allgemeine Java-Themen 5
T Wiederholte Abfrage? Allgemeine Java-Themen 5
B abfrage ob file ausgeführt wurde Allgemeine Java-Themen 4
Z Boolean Abfrage gibt kein Boolean zurück, aber warum? Allgemeine Java-Themen 6
P Google Abfrage auslesen Allgemeine Java-Themen 2
MQue Performance Methodenaufruf - if Abfrage Allgemeine Java-Themen 19
W ICQ Status Abfrage mit Java Allgemeine Java-Themen 3
MQue if- Abfrage Allgemeine Java-Themen 4
B Abfrage ob JRE installiert ist, JAR automatisch starten Allgemeine Java-Themen 5
MQue if Abfrage Allgemeine Java-Themen 27
MQue if- Abfrage Allgemeine Java-Themen 26
C Versionsstring Abfrage Allgemeine Java-Themen 7
G Tastatur abfrage Allgemeine Java-Themen 8
D Doppeltverschachtelte if-Abfrage Allgemeine Java-Themen 10
Z mit java htaccess - abfrage bestätigen/umgehen Allgemeine Java-Themen 2
U if Abfrage macht etwas falsch Allgemeine Java-Themen 2
G Problem mit if-Abfrage bei Benutzeingabe Allgemeine Java-Themen 2
P Java Acces Datenbank Problem ! (Brauche eine Abfrage) Allgemeine Java-Themen 5
K Abfrage ob JRE oder JDK auf System installiert ist. Allgemeine Java-Themen 12
T IF Abfrage + YES_NO Option mittels JOptionPane Allgemeine Java-Themen 3
U IF-Abfrage Allgemeine Java-Themen 17
H Java-Abfrage Allgemeine Java-Themen 9
A FileChooser Datei-Überschreiben Abfrage Allgemeine Java-Themen 2
F Java Passwort abfrage Allgemeine Java-Themen 2
S CDDB-Abfrage mit Java unter Linux? Allgemeine Java-Themen 4
L Datenbank Abfrage (Felder&Tabelle nicht fix) in ArrayLis Allgemeine Java-Themen 4
S Integer-splitten für Abfrage. Allgemeine Java-Themen 4
G Abfrage in datenbank Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben