Хранение целочисленных значений в виде констант в порядке перечисления в java [дубликат]


этот вопрос уже есть ответ здесь:

  • Java: возникли проблемы с объявлением перечисления с целочисленными константами 3 ответы

В настоящее время я создаю целочисленные константы следующим образом.

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

когда я пытаюсь сделать это в enum образом

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

и PAGE.SIGN_CREATE он должен вернуть 1;

6 82

6 ответов:

Ну, вы не можете сделать это таким образом. PAGE.SIGN_CREATE никогда не вернет 1; он вернет PAGE.SIGN_CREATE. Вот в чем суть перечисляемых типов.

однако, если вы хотите добавить несколько нажатий клавиш, вы можете добавить поля в свои перечисления, например:


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

а потом ты позвонишь PAGE.SIGN_CREATE.getValue() чтобы получить 0.

наиболее распространенная причина, по которой требуется целочисленная константа, связанная с каждым значением перечисления, - это взаимодействие с каким-либо другим компонентом, который все еще ожидает эти целые числа (например, протокол сериализации, который вы не можете изменить, или перечисления представляют столбцы в таблице и т. д.).

практически во всех случаях я предлагаю использовать EnumMap вместо. Он отделяет компоненты более полно, если это было проблемой, или если перечисления представляют индексы столбцов или что-то подобное, вы может легко вносить изменения позже (или даже во время выполнения, если это необходимо).

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

это, как правило, невероятно эффективно, тоже.

добавление таких данных в сам экземпляр enum может быть очень мощным, но чаще всего злоупотребляется.

Edit: только что понял, что блох обратился к этому в эффективном Java / 2nd edition, в Пункт 33: Использовать EnumMap вместо порядковой индексации.

можно использовать порядковый номер. Так что PAGE.SIGN_CREATE.ordinal() возвращает 1.

EDIT:

единственная проблема с этим заключается в том, что если вы добавляете, удаляете или переупорядочиваете значения перечисления, вы нарушите систему. Для многих это не проблема, так как они не будут удалять перечисления и будут только добавлять дополнительные значения в конце. Это также не хуже, чем целочисленные константы, которые также требуют, чтобы вы не перенумеровали их. Однако лучше всего использовать такую систему, как:

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

}

вы затем можно использовать getID. Так что PAGE.SIGN_CREATE.getID() возвращает 1.

вы можете сохранить это значение const в перечислении, как так. Но зачем вообще использовать const? Вы настаиваете на перечислении?

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

Edit:

Это зависит от того, что вы используете int для того, чтобы использовать EnumMap или поле экземпляра.

если вы хотите иметь возможность конвертировать integer вернуться к соответствующему enum с выбранным значением см. Constants.forValue(...) В автоматически сгенерированный код, но если нет ответа BlairHippo это лучший способ, чтобы сделать это.

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

Я нашел это полезным:

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