Mit Enum ist ordinalen Wert in switch-case-Anweisung
Für mein Projekt bin ich mit enums und ich brauche zur Umsetzung der switch-case-Anweisung, wo die Ordnungszahlen der Werte der bestimmten Enum geprüft werden, wie dieser Weg:
switch ( variable )
{
case MyEnum.A.ordinal():
return true;
case MyEnum.B.ordinal():
return true;
default:
return false;
}
Hinweis: Rückgabe-Werte sind nur ein Beispiel.
Leider, Eclipse (ich bin mit 1.6 JDK) gibt meine Zusammenstellung-Fehler " - Fall
Ausdrücke müssen Konstante Ausdrücke". Was sollte ich tun? Gibt es eine andere Methode als statische lookup-Tabelle, hier beschrieben: Konvertieren von enum Ordnungszahl zu enum-Typ ?
- Ich glaube, ich verstehe nicht, warum man mit der Ordnungszahl. Warum können Sie nicht einfach schalten Sie das enum selbst?
- Einfach nur neugierig, aber warum bist du mit enums, wenn Sie dann Variablen verwenden die ordinale Werte? Der Punkt des enums ist Ihre Art Sicherheit, aber die variable ist nicht Typ-sicher.. Naja, es könnte so etwas einfaches wie die Herstellung der Ordinalwert eine öffentliche Konstante Attribut statt der Zugriff über eine getter-Methode.
- Weil ich muss ordinalen Wert - enum-Werte sind nicht sinnvoll, für diesen bestimmten Zweck, denn Sie stehen in keinem Zusammenhang zu den Ergebnissen der switch-Anweisung.
- Ich muss zugeben, das macht für mich keinen Sinn - Wie kann man den enum-Wert nicht auf das Ergebnis der switch-Wert? Die Ordnungszahl wird nur ein index auf die enum-Werte (ein index, der sich ändern kann, wenn Sie fügen Sie ein neues enum-Wert) - Die Ordnungszahlen, indem es die Natur ist nichts weiter als eine vorübergehende Eigenschaft des enum.
- durch die Art und Weise, was Sie Fragen ist EnumSet
- Die enum-Mitglied kann werden gespeichert in einer Datenbank (mit Ihrer Ordnungszahl Wert), in dem Fall ist das nötig.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist, wie getan wird, vorausgesetzt, Sie haben eine serialisierte Ordnungszahl irgendwie, irgendwo. Gewohnter Weise beibehalten eines enum ist durch seinen Namen, nicht ordinal, obwohl. Auch sollten Sie nicht verwenden die Ordnungszahl in normalen Umständen, es sei denn, zu versuchen, so etwas wie EnumMap/Set. Natürlich, die enum kann nur ein port von C gleichermaßen Zeug und den Umgang mit den unvermeidlichen int, muss eine Transformation auf das Enum-Objekt.
Verwenden Sie einfach
Enum.values()
auf, um ein array bestelltordinal()
, da das array geklont jeder Zeit, halten Sie ein ref-Richtung ist ok.Nur bemerkt, dass Sie brauchen nur true und false, dass ist ein Art von Verhalten. Sie können die Verwendung von java.util.EnumSet oder eine einfache
long
, wenn mutig (und nicht mit mehr als 64 enum-Konstanten). zum Beispiel:Erste von allen, sollten Sie nicht verlassen sich auf die Ordnungszahl, die viel. Wenn möglich, stellen Sie Ihrer variable ein
String
(und zu transformieren, umenum
mitEnum.valueOf(string)
oder am besten machen Sie esenum
.Wenn Sie wirklich nicht können, dann verwenden Sie
enum.values()[ordinal]
.Dann verwenden Sie die enum in-Schalter.values()
Klone der array, Sie wären besser dran, wenn es in eine statische variable.Die Antwort Zielvorgaben @Riaan Kommentar auf Konstante vs-Methode enums-und performance-Gründen nicht direkt Antworten der OP Frage, so kann es als Rauschen, nehme ich an.
Ich glaube jedoch, es ist wichtig zu verstehen, wie das Innenleben.
Nahm ich den benchmark aus seinem Beispiel und verbessert es zum löschen der garbage collection und der string-Erstellung, übernimmt 90% der Ausführungszeit. Hinzugefügt warm-up-phase, um sicherzustellen hotspot tatsächlich stellt die Methoden.
Gibt es einige mehr, die benchmark ist effektiv callsite-test. Die Optimierung für callsites ganz anders sind, für 1, für 2 für einige mehr und für noch mehr-mehr. Eine callsite ist eine Anrufung des abstrakten (oder auch nur überschriebene) Methode.
Unten ist der test mit 6 enums Konstanten:
War der code ausgeführt w/
-server -XX:+PrintCompilation
Optionen.Der Unterschied ist nicht riesig, natürlich. Aber das ist nicht die interessante Frage. Wenn Sie testen die version mit 2 enum-Konstanten-obwohl, das Ergebnis kann erheblich unterschiedlich sein. Für 2-Aufruf von Websites erzeugt der compiler den code von inlinining die Methode in Frage. In dem test oben, die entfernen würde, gesamte Aufruf booleanValue und können sogar führen Sie den test in O(1).
Den lustigsten Teil geht jedoch von 2 bis 3 enum-Konstanten, wenn der compiler gestartet wird die Verwendung von inline caches und dann die Konstante, und WOW Magie, das alles verändert.
Die Quintessenz ist: die geeignete benchmark ist wirklich schwer und erfordert einige Kenntnisse, wie der JIT-kompiliert, wenn der GC könnte ein Problem sein (entweder entfernen oder Sie zu umarmen) und so weiter.
Links:
verwenden Sie einfach den enum-Konstanten:
vorausgesetzt, so etwas wie:
aber hüten Sie sich vor
NullPointerException
(wennvariable
istnull
)Was Sie Fragen ist wohl:
Wenn Sie die Schalter in einer Methode im enum selbst:
Und in einer anderen Klasse:
Es ist leicht zu vergessen, ein update der switch-Anweisungen wenn Sie weitere hinzufügen, enum, also eine bessere Wette wäre, legen Sie die Methoden, wie dies in den enum selbst und verwenden Sie Konstanten-spezifische Implementierungen von Methoden:
Diese Weise, wenn Sie jemals fügen Sie ein neues enum-Wert, der compiler wird Sie daran erinnern, erklären die getBooleanValue Methode und verwenden Sie einfach
A.getBooleanValue();
wo Sie es brauchen.Als wurde darauf hingewiesen, in den Kommentaren, eine andere option ist diese:
Es ist eine Frage der Präferenz und abhängig von der jeweiligen situation ab. Wenn Sie einfach zurückgeben eines Wertes für jede enum-der Konstruktor-version ist plausibel, aber ich finde es weniger lesbar. Bedenken über dieses besser ist unbegründet, wie Sie sehen können, Sie zu testen:
MyEnum
nicht kompiliert werden kann. Ich habe schreiben die benchmark, die Konstanten, die ist etwas schneller auf 40M Elemente, die benchmarks verbringt die meisten, wenn die Zeit, in der Modul-und der String-Erstellung, so müssen die sehr viele Auswirkungen hat.Eine bessere Lösung wäre so etwas wie dieses:
enum:
Umsetzung:
Mann Pak Hong, Dave ([email protected])