web-dev-qa-db-fra.com

Stocker des valeurs entières sous forme de constantes de manière Enum en java

Je crée actuellement des constantes entières de la manière suivante.

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;
}

Quand j'essaie de le faire de manière énime 

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

et quand j’ai utilisé PAGE.SIGN_CREATE, il devrait renvoyer 1;

84
Labeeb Panampullan

Eh bien, vous ne pouvez pas le faire de cette façon. PAGE.SIGN_CREATE ne retournera jamais 1; il retournera PAGE.SIGN_CREATE. C'est le point des types énumérés.

Toutefois, si vous souhaitez ajouter quelques touches, vous pouvez ajouter des champs à vos énumérations, comme ceci:


    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; }
    }

Et puis vous appelez PAGE.SIGN_CREATE.getValue() pour obtenir 0.

158
BlairHippo

La raison la plus courante de vouloir une constante entière associée à chaque valeur enum est d'interagir avec un autre composant qui attend toujours ces entiers (par exemple, un protocole de sérialisation que vous ne pouvez pas modifier ou les énumérations représentent des colonnes dans une table, etc.). .

Dans presque tous les cas, je suggère d'utiliser plutôt un EnumMap. Il découple plus complètement les composants, si tel était le problème ou si les énumérations représentent des index de colonnes ou quelque chose de similaire, vous pouvez facilement apporter des modifications ultérieurement (ou même au moment de l'exécution si besoin est).

 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);

C'est aussi incroyablement efficace.

Ajouter de telles données à l'instance enum elle-même peut être très puissant, mais il est le plus souvent abusé.

Edit: Je viens de me rendre compte que Bloch a traité cela dans Effective Java/2ème édition, dans Point 33: Utiliser EnumMap au lieu de l’indexation ordinale .

21
Mark Peters

Vous pouvez utiliser ordinal . Donc, PAGE.SIGN_CREATE.ordinal() renvoie 1.

MODIFIER:

Le seul problème avec cela est que si vous ajoutez, supprimez ou réorganisez les valeurs enum, vous casserez le système. Pour beaucoup, ce n'est pas un problème car ils ne supprimeront pas les énumérations et ne feront qu'ajouter des valeurs supplémentaires à la fin. Ce n’est pas pire que les constantes entières qui exigent également de ne pas les renuméroter. Cependant, il est préférable d'utiliser un système tel que:

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;
  }

}

Vous pouvez ensuite utiliser getID. Donc, PAGE.SIGN_CREATE.getID() renvoie 1.

14
Adam

Vous pouvez stocker cette valeur const dans l'énumération comme ceci. Mais pourquoi même utiliser le const? Est-ce que vous persistez l'énum?

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"));
   }
}

Modifier:

Cela dépend de ce que vous utilisez les int pour savoir s'il faut utiliser EnumMap ou un champ d'instance.

2
TJR

si vous voulez pouvoir reconvertir integer en enum correspondant avec la valeur sélectionnée, voir Constants.forValue(...) dans le code généré automatiquement, mais dans le cas contraire, la réponse de BlairHippo est la meilleure façon de le faire.

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

J'ai trouvé cela utile:

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