Как отобразить значение обратно в перечисление? - PullRequest
10 голосов
/ 01 апреля 2011

Учитывая перечисление, где каждый экземпляр связан с некоторым значением:

public enum SQLState
{
  SUCCESSFUL_COMPLETION("00000"),
  WARNING("01000");

  private final String code;
  SQLState(String code)
  {
    this.code = code;
  }
}

Как я могу построить Карту для эффективного обратного просмотра? Я попробовал следующее:

public enum SQLState
{
  SUCCESSFUL_COMPLETION("00000"),
  WARNING("01000");

  private final String code;
  private static final Map<String, SQLState> codeToValue = Maps.newHashMap();
  SQLState(String code)
  {
    this.code = code;
    codeToValue.put(code, this); // problematic line
  }
}

но Java жалуется: Illegal reference to static field from initializer. То есть статическая карта инициализируется после всех значений перечисления, поэтому вы не можете ссылаться на нее из конструктора. Есть идеи?

Ответы [ 3 ]

13 голосов
/ 01 апреля 2011

использование:

static {
  for (SQLState sqlState : values()){
     codeToValue.put(sqlState.code, sqlState);
  }
}
1 голос
/ 08 июня 2012

Поскольку вы используете Guava, я рекомендую использовать следующий код:

public enum SQLState {

    SUCCESSFUL_COMPLETION("00000"),
    WARNING("01000"),
    ;

    private final String code;
    private SQLState(String code) {
        this.code = code;
    }

    public static final Function<SQLState,String> EXTRACT_CODE = new Function<SQLState,String>() {
        @Override
        public String apply(SQLState input) {
            return input.code;
        }
    };

    public static final Map<String, SQLState> CODE_TO_VALUE = ImmutableMap.copyOf( Maps.uniqueIndex(EnumSet.allOf(SQLState.class), EXTRACT_CODE) );

    public static void main(String[] args) {
        System.out.println( SQLState.CODE_TO_VALUE.get("00000") );
    }

}

Получается, как и ожидалось: "SUCCESSFUL_COMPLETION"

Использование статического инициализатора хорошо, когда вы не можете инициализировать финальные переменные встроенными, но в этом случае с Guava вы действительно можете использовать функциональный подход с функциями Guava.

Далее, вы делаете свой список неизменным в одно и то же время, и это хорошо, если вам нужно обнародовать его

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


Проверьте Картографическая документация uniqueIndex , которая является действительно классной функцией Guava, которая позволяет индексировать любой объект по любому его атрибуту. Если многие объекты имеют одно и то же значение атрибута, вы можете использовать Multimaps.index, который для каждого ключа предоставит вам список объектов, имеющих этот атрибут.

0 голосов
/ 01 апреля 2011

Инициализировать статическую карту в статическом блоке {...} перед конструктором.Посмотрите на статические блоки инициализатора.

...