Wie konvertiere ich einen Aufzählungswert in int?

240

Ich habe eine Funktion, die einen Typ int zurückgibt. Ich habe jedoch nur einen Wert der TAX-Aufzählung.

Wie kann ich den TAX-Aufzählungswert in ein int umwandeln?

public enum TAX {
    NOTAX(0),SALESTAX(10),IMPORTEDTAX(5);

    private int value;
    private TAX(int value){
        this.value = value;
    }
}

TAX var = TAX.NOTAX; // This value will differ

public int getTaxValue()
{
  // what do do here?
  // return (int)var;
}
vrbilgi
quelle
1
Mögliches Duplikat von How to match int to enum
malat

Antworten:

354

Sie müssten die Aufzählung valueirgendwie aussetzen , z

public enum Tax {
    NONE(0), SALES(10), IMPORT(5);

    private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

...

public int getTaxValue() {
    Tax tax = Tax.NONE; // Or whatever
    return tax.getValue();
}

(Ich habe die Namen geändert, um sie etwas konventioneller und lesbarer zu machen, übrigens.)

Dies setzt voraus, dass Sie den im Konstruktor zugewiesenen Wert möchten. Wenn Sie dies nicht möchten, müssen Sie uns weitere Informationen geben.

Jon Skeet
quelle
1
@likejiujitsu: Das geht in die entgegengesetzte Richtung. In dieser Frage, die OP bereits hat einen Wert vom Typ Taxund will den numerischen Wert von ihm bekommen.
Jon Skeet
Ich habe es gerade versucht und festgestellt, dass es fehlschlägt. myEnumValue = MyEnum.valueOf(myInt);Das Argument muss vom Typ String sein - oder fehlt mir etwas?
Likejudo
Diese Lösung ist schlimmer als nichts. Scheint, dass Enums in Java einfach nicht verwendet werden sollten? Oder hat JDK 1.8 das geändert?
Ebyrob
@ebyrob: Angesichts der Abstimmung scheinen viele Leute mit Ihnen nicht einverstanden zu sein, so wie ich. Wenn Sie einen festen Wertesatz wünschen, sind Aufzählungen absolut in Ordnung.
Jon Skeet
209

Ich bevorzuge das:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

dann:

//cast enum to int
int color = Color.Blue.ordinal();
vivia
quelle
34
Dies ist falsch / wird von Joshua Bloch in seinem Buch Effective Java (2nd ed) nicht empfohlen. Siehe Punkt 31.
user504342
43
@ user504342 Ich habe nicht die 2. Auflage des Buches. Können Sie uns bitte mitteilen, warum dies nicht empfohlen wird?
Likejudo
17
2 Gründe: Erstens wird jede Zuordnung zwischen den Ordnungswerten und den Konstanten unterbrochen, wenn neue Konstanten hinzugefügt werden, und zweitens empfehlen die API-Dokumente ausdrücklich dagegen.
Jordanpg
8
So sauber und perfekt. Ich sehe ein paar "mach es nicht" und "nicht empfohlen". Ich muss nachforschen, warum es als schlecht angesehen wird. Einige der aufgeblähten Proben sehen IMO schlecht aus. So viel Arbeit, um eine so einfache Aufgabe zu erledigen.
Herb Meehan
4
In einem Team, sind Sie ziemlich sicher , dass auf Ihrer Co-Entwickler einen Wert in der Mitte (schlimmer am Anfang), oder einfach nur sortieren sie hinzufügen , weil sie nichts zu tun haben und völlig Chaos mit dem Code.ordinal()
Michael Laffargue
18

Wenn Sie den Wert möchten, den Sie im Konstruktor zuweisen, müssen Sie der Enum-Definition eine Methode hinzufügen, um diesen Wert zurückzugeben.

Wenn Sie eine eindeutige Nummer wünschen, die den Aufzählungswert darstellt, können Sie diese verwenden ordinal().

unholysampler
quelle
2
Achtung. Es gibt viel mehr Entwicklungs-Anti-Muster, auf die sich ordinal()als gültige Anwendungsfälle stützen ordinal(). Wenn Sie einen eindeutigen Wert für das speichern müssen, speichern Sie enumeinfach das enum. Es gibt EnumSets, Listen von Enums, EnumMaps und fast jede andere Enum-Sammlung, die Sie möglicherweise zur Verfügung haben möchten.
Edwin Buck
1
@EdwinBuck: Das ist gut darauf hinzuweisen, ich wollte nur die Existenz von erwähnen, ordinal()weil das OP nicht klar gemacht hat, was er wollte, dass der Int tatsächlich ist.
Unholysampler
Nicht ordinal werden. Bitte überprüfen Sie die Enum-API diesbezüglich. Up-Vote entfernt.
Luftkissenfahrzeug voller Aale
3
Ich frage mich, was ordinal()die Leute über die Verwendung von intern innerhalb der Aufzählung selbst denken. Zum Beispiel, sagen , ich habe eine Enumeration „genannt Season“ , die die Werte enthalten Spring, Summer, Autumn, und Winter, und es hat eine öffentliche Methode aufgerufen , next()die zurückgibt values()[(ordinal() + 1) % 4] äußerlich sieht kein Code jemals die Ordnungszahl, und es wird nie zusätzliche Mitglieder in diesem Enum sein, es scheint also ein gültiger Anwendungsfall zu sein.
Darrel Hoffman
1
@DarrelHoffman Mein Gefühl ist, dass dies in Ordnung ist, da die einzigen starken Argumente, die ich gegen die Verwendung von ordinal()Scharnieren für weit entfernten Code sehe , durch Änderungen an den Enum-Aufzählungskonstanten gebrochen werden. Wenn Sie die Konstanten der Aufzählung ändern möchten, müssen Sie sich bereits in dieser Datei befinden. Die meisten Aufzählungen sind ziemlich kurz, und wenn dies nicht der Fall ist, sollten Sie die Datei trotzdem gründlicher überprüfen. In beiden Fällen sollten Sie wahrscheinlich next()trotzdem einen Komponententest für Ihre Methode durchführen lassen.
Alan Hensley
12

Manchmal erleichtert ein C # -Ansatz das Leben in der Java-Welt ..:

class XLINK {
static final short PAYLOAD = 102, ACK = 103, PAYLOAD_AND_ACK = 104;
}
//Now is trivial to use it like a C# enum:
int rcv = XLINK.ACK;
Vladi
quelle
Für mich ist dies der wünschenswerteste Weg. Ich bekomme die Vorteile von Enum (Code Clarity), einem DB-freundlichen Datentyp, und ich muss nicht nach 100 Enum-Alternativen suchen, um dies auf "Android-Art" zu tun. Einfach und effektiv.
John Ward
Nett. Es ist, als ob die Java-Enumeration völlig von der Realität getrennt ist, wofür eine Enumeration verwendet wird ... besonders wenn die Leute sie dann für Dinge wie Singletons missbrauchen. Dieser Ansatz hat den Nachteil, dass es nicht einfach ist, alle Werte zu erhalten.
Nyerguds
Hat dies nicht den Nachteil, dass versucht wird, einen Enum-Wert an eine Methode zu übergeben? Sie können einen XLINK nicht mehr an eine Methode übergeben, da er nichts Konkretes darstellt. Sie verlieren die Eingabe in Ihre Methode. Die Methodensignatur müsste anstelle von XLINK kurz lauten.
Dustin Jensen
2

Vielleicht ist es besser, eine String-Darstellung als eine Ganzzahl zu verwenden, da der String weiterhin gültig ist, wenn der Aufzählung Werte hinzugefügt werden. Sie können die name () -Methode der Aufzählung verwenden, um den Aufzählungswert in einen String zu konvertieren, und die valueOf () -Methode der Aufzählung, um erneut eine Aufzählungsdarstellung aus dem String zu erstellen. Das folgende Beispiel zeigt, wie der Aufzählungswert in String und zurück konvertiert wird (ValueType ist eine Aufzählung):

ValueType expected = ValueType.FLOAT;
String value = expected.name();

System.out.println("Name value: " + value);

ValueType actual = ValueType.valueOf(value);

if(expected.equals(actual)) System.out.println("Values are equal");
Mike
quelle
1
public enum Tax {

NONE(1), SALES(2), IMPORT(3);

private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

class Test {
    System.out.println(Tax.NONE);    //Just an example.
}
Ieshaan Saxena
quelle
0

Ein etwas anderer Ansatz (zumindest unter Android) besteht darin, die IntDef- Annotation zu verwenden, um eine Reihe von int-Konstanten zu kombinieren

@IntDef({NOTAX, SALESTAX, IMPORTEDTAX})
@interface TAX {}
int NOTAX = 0;
int SALESTAX = 10;
int IMPORTEDTAX = 5;

Verwendung als Funktionsparameter:

void computeTax(@TAX int taxPercentage){...} 

oder in einer Variablendeklaration:

@TAX int currentTax = IMPORTEDTAX;
mir
quelle