it-swarm.com.de

Speichern von ganzzahligen Werten als Konstanten in Enum-Art in Java

Momentan erstelle ich Integer-Konstanten auf folgende Weise.

public class Constants {
public static int SIGN_CREATE=0;
public static int SIGN_CREATE=1;
public static int HOME_SCREEN=2;
public static int REGISTER_SCREEN=3;
}

Wenn ich versuche, dies auf enum-Art zu tun 

public enum PAGE{SIGN_CREATE,SIGN_CREATE,HOME_SCREEN,REGISTER_SCREEN}

und wenn ich PAGE.SIGN_CREATE verwendete, sollte es 1 zurückgeben;

84

Nun, Sie können es nicht ganz so machen. PAGE.SIGN_CREATE gibt niemals 1 zurück; es wird PAGE.SIGN_CREATE zurückgegeben. Das ist der Punkt der aufgezählten Typen.

Wenn Sie jedoch ein paar Tastatureingaben hinzufügen möchten, können Sie Ihrer Aufzählung Felder hinzufügen:


    public enum PAGE{
        SIGN_CREATE(0),
        SIGN_CREATE_BONUS(1),
        HOME_SCREEN(2),
        REGISTER_SCREEN(3);

        private final int value;

        PAGE(final int newValue) {
            value = newValue;
        }

        public int getValue() { return value; }
    }

Und dann rufen Sie PAGE.SIGN_CREATE.getValue() an, um 0 zu erhalten.

158
BlairHippo

Der häufigste gültige Grund, eine Integer-Konstante für jeden Enumerationswert zu benötigen, ist die Interoperabilität mit einer anderen Komponente, die noch diese Integer-Werte erwartet (z. B. ein Serialisierungsprotokoll, das Sie nicht ändern können, oder die Enumerationen stellen Spalten in einer Tabelle dar usw.) .

In fast allen Fällen empfehle ich die Verwendung einer EnumMap. Sie entkoppelt die Komponenten vollständiger, wenn dies das Problem war, oder wenn die Aufzählungen Spaltenindizes oder ähnliches darstellen, können Sie später (oder bei Bedarf sogar zur Laufzeit) Änderungen vornehmen.

 private final EnumMap<Page, Integer> pageIndexes = new EnumMap<Page, Integer>(Page.class);
 pageIndexes.put(Page.SIGN_CREATE, 1);
 //etc., ...

 int createIndex = pageIndexes.get(Page.SIGN_CREATE);

Es ist in der Regel auch unglaublich effizient.

Das Hinzufügen von Daten zur Enum-Instanz selbst kann sehr mächtig sein, wird aber in den meisten Fällen missbraucht.

Edit: Gerade realisiert Bloch hat dieses Problem in Effective Java/2nd Edition in Punkt 33 gelöst: Verwenden Sie EnumMap anstelle der ordinalen Indizierung .

21
Mark Peters

Sie können ordinal verwenden. PAGE.SIGN_CREATE.ordinal() gibt also 1 zurück.

BEARBEITEN:

Das einzige Problem dabei ist, dass durch das Hinzufügen, Entfernen oder Neuordnen der Aufzählungswerte das System beschädigt wird. Für viele ist dies kein Problem, da sie keine Aufzählungen entfernen und am Ende nur zusätzliche Werte hinzufügen. Es ist auch nicht schlechter als ganzzahlige Konstanten, für die Sie auch nicht neu nummeriert werden müssen. Am besten verwenden Sie jedoch ein System wie:

public enum PAGE{
  SIGN_CREATE0(0), SIGN_CREATE(1) ,HOME_SCREEN(2), REGISTER_SCREEN(3)

  private int id;

  PAGE(int id){
    this.id = id;
  }

  public int getID(){
    return id;
  }

}

Sie können dann getID verwenden. PAGE.SIGN_CREATE.getID() gibt also 1 zurück.

14
Adam

Sie könnten diesen const-Wert wie folgt in der Aufzählung speichern. Aber wieso überhaupt die const? Beharrst du am Enum?

public class SO3990319 {
   public static enum PAGE {
      SIGN_CREATE(1);
      private final int constValue;

      private PAGE(int constValue) {
         this.constValue = constValue;
      }

      public int constValue() {
         return constValue;
      }
   }

   public static void main(String[] args) {
      System.out.println("Name:    " + PAGE.SIGN_CREATE.name());
      System.out.println("Ordinal: " + PAGE.SIGN_CREATE.ordinal());
      System.out.println("Const:   " + PAGE.SIGN_CREATE.constValue());

      System.out.println("Enum: " + PAGE.valueOf("SIGN_CREATE"));
   }
}

Bearbeiten:

Es hängt davon ab, wofür Sie die Int's verwenden, ob Sie EnumMap oder ein Instanzfeld verwenden.

2
TJR

wenn Sie integer mit dem ausgewählten Wert wieder in die entsprechende enum konvertieren möchten, sehen Sie Constants.forValue(...) in automatisch generiertem Code. Ist dies nicht der Fall, ist die Antwort von BlairHippo die beste Methode.

public enum Constants
{
SIGN_CREATE(0),
SIGN_CREATE(1),
HOME_SCREEN(2),
REGISTER_SCREEN(3);

    public static final int SIZE = Java.lang.Integer.SIZE;

    private int intValue;
    private static Java.util.HashMap<Integer, Constants> mappings;
    private static Java.util.HashMap<Integer, Constants> getMappings()
    {
        if (mappings == null)
        {
            synchronized (Constants.class)
            {
                if (mappings == null)
                {
                    mappings = new Java.util.HashMap<Integer, Constants>();
                }
            }
        }
        return mappings;
    }

    private Constants(int value)
    {
        intValue = value;
        getMappings().put(value, this);
    }

    public int getValue()
    {
        return intValue;
    }

    public static Constants forValue(int value)
    {
        return getMappings().get(value);
    }
}
0
Top-Master

Ich fand das hilfreich:

http://dan.clarke.name/2011/07/enum-in-Java-with-int-conversion/

public enum Difficulty
{
    EASY(0),
    MEDIUM(1),
    HARD(2);

    /**
    * Value for this difficulty
    */
    public final int Value;

    private Difficulty(int value)
    {
        Value = value;
    }

    // Mapping difficulty to difficulty id
    private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>();
    static
    {
        for (Difficulty difficulty : Difficulty.values())
            _map.put(difficulty.Value, difficulty);
    }

    /**
    * Get difficulty from value
    * @param value Value
    * @return Difficulty
    */
    public static Difficulty from(int value)
    {
        return _map.get(value);
    }
}
0
Clayton Bell