2008-10-27 6 views
21

Учитывая следующий Java перечисление:Как преобразовать строковый результат перечисления с переопределенным toString() обратно в enum?

public enum AgeRange { 

    A18TO23 { 
     public String toString() {   
      return "18 - 23"; 
     } 
    }, 
    A24TO29 { 
     public String toString() {   
      return "24 - 29"; 
     } 
    }, 
    A30TO35 { 
     public String toString() {   
      return "30 - 35"; 
     } 
    }, 

} 

Есть ли способ, чтобы преобразовать строковое значение «18 - 23» к соответствующему значению перечисления т.е. AgeRange.A18TO23?

Спасибо!

ответ

30

Самый лучший и простой способ сделать это так:

public enum AgeRange { 
    A18TO23 ("18-23"), 
    A24TO29 ("24-29"), 
    A30TO35("30-35"); 

    private String value; 

    AgeRange(String value){ 
     this.value = value; 
    } 

    public String toString(){ 
     return value; 
    } 

    public static AgeRange getByValue(String value){ 
     for (final AgeRange element : EnumSet.allOf(AgeRange.class)) { 
      if (element.toString().equals(value)) { 
       return element; 
      } 
     } 
     return null; 
    } 
} 

Тогда вам нужно просто вызвать метод getByValue() с вводом String в этом.

7

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

+0

Это гораздо лучший способ справиться с этим. Затем карта создается, когда перечисляется, и работает намного быстрее, чем итерация массива. – 2008-10-27 15:36:49

+0

Я тоже рассматриваю этот метод, но у меня есть только около 15 значений в этом перечислении. Является ли еще более эффективным создание карты? – Walter 2008-10-29 02:43:59

+0

Наверное, нет, честно говоря. Хэш-таблицы отлично подходят для больших объемов данных, но я подозреваю, что сравнение 15 значений (в худшем случае) будет примерно таким же быстрым, как получение хэш-кода, поиск правильного ведра и т. Д. – 2008-10-29 06:24:29

2
for (AgeRange ar: EnumSet.allOf(AgeRange)) { 
    if (ar.toString().equals(inString)) { 
     myAnswer = ar; 
     break; 
    } 
} 

Или что-то в этом роде? Просто набрал, не пропустил компилятор. Простите (комментарий) опечатки ...

Или используйте такую ​​логику, чтобы построить карту один раз. Избегайте итерации во время выполнения. Хорошая идея, Джон.

2

Класс переопределяет значение «toString()» - поэтому, чтобы получить обратную операцию, вам необходимо переопределить valueOf(), чтобы перевести вывод toString() обратно в значения Enum.

public enum AgeRange { 

    A18TO23 { 
     public String toString() {   
       return "18 - 23"; 
     } 
     public AgeRange valueOf (Class enumClass, String name) { 
       return A18T023 
     } 
    }, 

    . 
    . 
    . 
} 

Покупатель остерегается - Неоткомпилированная и непроверенные ...

Механизм для toString() и valueOf() документированная часть API

0

Вы могли бы попробовать что-то вроде следующего?

static AgeRange fromString(String range) { 
    for (AgeRange ageRange : values()) { 
     if (range.equals(ageRange.toString())) { 
      return ageRange; 
     } 
    } 
    return null; 
} 

Или, как другие предложили, используя подход кэширования:

private static Map<String, AgeRange> map; 

private static synchronized void registerAgeRange(AgeRange ageRange) { 
    if (map == null) { 
     map = new HashMap<String, AgeRange>(); 
    } 
    map.put(ageRange.toString(), ageRange); 
} 

AgeRange() { 
    registerAgeRange(this); 
} 

static AgeRange fromString(String range) { 
    return map.get(range); 
} 
4

Согласно эффективной Java (2-е изд) пункта 30, это может быть (это намного быстрее, чем цикл)

public enum AgeRange { 
     A18TO23("18-23"), 
     A24TO29("24-29"), 
     A30TO35("30-35"); 

     private final String value; 

     AgeRange(String value){ 
      this.value = value; 
     } 

     @Override public String toString(){ 
      return value; 
     } 

     private static final Map<String, AgeRange> stringToEnum = 
      new HashMap<String, AgeRange>(); 

     static { 
      for (AgeRange r : values()) { 
       stringToEnum.put(r.toString(), r); 
      } 
     } 

     public static AgeRange getByValue(String value){ 
      return stringToEnum.get(value); 
     } 
}