Как преобразовать строковый результат перечисления с переопределенным toString() обратно в enum?
Учитывая следующее перечисление java:
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?
Спасибо!
Ответы
Ответ 1
Самый лучший и простой способ сделать это:
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
в нем.
Ответ 2
Вы всегда можете создать карту из строки в значение - сделайте это статически, поэтому вам нужно будет только ее сопоставить, считая, что возвращаемая строка остается неизменной с течением времени. Насколько мне известно, ничего не было встроено.
Ответ 3
В соответствии с эффективным 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);
}
}
Ответ 4
for (AgeRange ar: EnumSet.allOf(AgeRange)) {
if (ar.toString().equals(inString)) {
myAnswer = ar;
break;
}
}
Или что-то в этом роде? Просто набрал, не пропустил компилятор. Простите (комментарий) опечатки...
Или используйте такую логику, чтобы построить карту один раз. Избегайте итерации во время выполнения. Хорошая идея, Джон.
Ответ 5
Класс переопределяет "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
Ответ 6
Вы можете попробовать что-то вроде следующего:
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);
}