1050 Stimmen

Warum kann ich die switch-Anweisung nicht für einen String verwenden?

Wird diese Funktion in einer späteren Java-Version enthalten sein?

Kann mir jemand erklären, warum ich das nicht tun kann, d.h. die technische Art und Weise, wie Java's switch Aussage funktioniert?

203 Stimmen

Es ist in SE 7. 16 Jahre nach seinem Antrag. download.oracle.com/javase/tutorial/java/nutsandbolts/

88 Stimmen

Sun war ehrlich in ihrer Bewertung: "Don't hold your breath." lol, bugs.sun.com/bugdatabase/view_bug.do?bug_id=1223179

3 Stimmen

@raffian Ich glaube, das liegt daran, dass sie zweimal 'seufzte'. Sie waren auch ein bisschen spät dran mit ihrer Antwort, nach fast 10 Jahren. Vielleicht hat sie damals Lunchpakete für ihre Enkelkinder gepackt.

19voto

DJClayworth Punkte 25458

James Curran bringt es auf den Punkt: "Schalter, die auf ganzen Zahlen basieren, können zu sehr effizientem Code optimiert werden. Schalter, die auf anderen Datentypen basieren, können nur zu einer Reihe von if()-Anweisungen kompiliert werden. Aus diesem Grund sind in C & C++ nur Schalter für Integer-Typen erlaubt, da es bei anderen Typen sinnlos war."

Meiner Meinung nach, und das ist nur meine Meinung, müssen Sie, sobald Sie mit Nicht-Primitiven arbeiten, über "gleich" und "==" nachdenken. Erstens kann der Vergleich zweier Zeichenketten eine ziemlich langwierige Prozedur sein, was zu den oben erwähnten Leistungsproblemen beiträgt. Zweitens, wenn auf Zeichenketten umgeschaltet wird, besteht Bedarf für das Umschalten auf Zeichenketten ohne Berücksichtigung der Groß-/Kleinschreibung, das Umschalten auf Zeichenketten unter Berücksichtigung/Unterdrückung des Gebietsschemas, das Umschalten auf Zeichenketten basierend auf regex..... Ich würde eine Entscheidung gutheißen, die den Sprachentwicklern viel Zeit spart und den Programmierern nur wenig Zeit abverlangt.

12voto

PhiLho Punkte 39496

Neben den oben genannten guten Argumenten möchte ich hinzufügen, dass viele Menschen heute die switch als ein veralteter Rest der prozeduralen Vergangenheit von Java (zurück zu C-Zeiten).

Ich teile diese Meinung nicht ganz, denke ich. switch kann in einigen Fällen nützlich sein, zumindest wegen seiner Geschwindigkeit, und ist auf jeden Fall besser als eine Reihe von kaskadierenden numerischen else if Ich habe in irgendeinem Code gesehen...

Aber es lohnt sich in der Tat, den Fall zu betrachten, in dem Sie einen Schalter benötigen, und zu sehen, ob er nicht durch etwas mehr OO ersetzt werden kann. Zum Beispiel Enums in Java 1.5+, vielleicht HashTable oder eine andere Sammlung (manchmal bedauere ich, dass wir keine (anonymen) Funktionen als Bürger erster Klasse haben, wie in Lua - das keinen Schalter hat - oder JavaScript) oder sogar Polymorphismus.

8voto

hyper-neutrino Punkte 5001

Wenn Sie nicht JDK7 oder höher verwenden, können Sie hashCode() um sie zu simulieren. Denn String.hashCode() in der Regel unterschiedliche Werte für unterschiedliche Zeichenketten und immer gleiche Werte für gleiche Zeichenketten zurückgibt, ist es ziemlich zuverlässig (unterschiedliche Zeichenketten kann denselben Hash-Code erzeugen, den @Lii in einem Kommentar erwähnt hat, z. B. "FB" y "Ea" ) Siehe [Dokumentation](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode() "String Hashcode") .

Der Code würde also wie folgt aussehen:

String s = "<Your String>";

switch(s.hashCode()) {
case "Hello".hashCode(): break;
case "Goodbye".hashCode(): break;
}

Auf diese Weise schalten Sie technisch gesehen eine int .

Alternativ können Sie auch den folgenden Code verwenden:

public final class Switch<T> {
    private final HashMap<T, Runnable> cases = new HashMap<T, Runnable>(0);

    public void addCase(T object, Runnable action) {
        this.cases.put(object, action);
    }

    public void SWITCH(T object) {
        for (T t : this.cases.keySet()) {
            if (object.equals(t)) { // This means that the class works with any object!
                this.cases.get(t).run();
                break;
            }
        }
    }
}

4voto

Charles Goodwin Punkte 6206

Seit Jahren verwenden wir dafür einen (quelloffenen) Präprozessor.

//#switch(target)
case "foo": code;
//#end

Die vorverarbeiteten Dateien tragen den Namen Foo.jpp und werden mit einem Ameisenskript zu Foo.java verarbeitet.

Der Vorteil ist, dass es in Java verarbeitet wird, das auf 1.0 läuft (obwohl wir normalerweise nur bis 1.4 unterstützen). Außerdem war es viel einfacher, dies zu tun (viele String-Switches), als es mit Enums oder anderen Workarounds zu umgehen - der Code war viel einfacher zu lesen, zu warten und zu verstehen. IIRC (kann keine Statistiken oder technische Argumentation an dieser Stelle zur Verfügung stellen) war es auch schneller als die natürlichen Java-Äquivalente.

Der Nachteil ist, dass Sie Java nicht bearbeiten, so dass der Arbeitsablauf etwas komplizierter ist (bearbeiten, verarbeiten, kompilieren/testen), und dass eine IDE eine Verknüpfung zur Java-Datei herstellt, die etwas umständlich ist (der Schalter wird zu einer Reihe von logischen if/else-Schritten), und die Reihenfolge der Schalterfälle wird nicht beibehalten.

Ich würde es nicht für 1.7+ empfehlen, aber es ist nützlich, wenn Sie Java programmieren wollen, das auf ältere JVMs abzielt (da Joe Public selten die neueste Version installiert hat).

Sie können es bekommen von SVN oder durchsuchen Sie die Code online . Sie benötigen EBuild um es so zu bauen, wie es ist.

4voto

plugwash Punkte 8413

In anderen Antworten wurde gesagt, dass dies in Java 7 hinzugefügt wurde, und es wurden Umgehungsmöglichkeiten für frühere Versionen genannt. Diese Antwort versucht, das "Warum" zu beantworten

Java war eine Reaktion auf die Überkomplexität von C++. Es sollte eine einfache, saubere Sprache sein.

String hat ein wenig Sonderfallbehandlung in der Sprache, aber es scheint mir klar, dass die Designer versucht haben, die Menge an Sonderfällen und syntaktischem Zucker auf ein Minimum zu beschränken.

Das Umschalten auf Strings ist unter der Haube ziemlich komplex, da Strings keine einfachen primitiven Typen sind. Zu der Zeit, als Java entwickelt wurde, war dies keine übliche Funktion und passt nicht wirklich gut zu dem minimalistischen Design. Zumal man sich entschlossen hatte, == für Strings nicht als Sonderfall zu verwenden, wäre es (und ist) etwas seltsam, wenn case funktioniert, wo == nicht funktioniert.

Zwischen 1.0 und 1.4 blieb die Sprache selbst weitgehend unverändert. Die meisten Verbesserungen an Java betrafen die Bibliotheken.

Das alles änderte sich mit Java 5, die Sprache wurde erheblich erweitert. Weitere Erweiterungen folgten in den Versionen 7 und 8. Ich vermute, dass diese Änderung der Einstellung durch den Aufstieg von C# vorangetrieben wurde

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X