Переопределить значениеof() и toString() в перечислении Java
Значения в my enum
- это слова, которые должны иметь пробелы в них, но перечисления не могут иметь пробелов в своих значениях, поэтому все они сгруппированы. Я хочу переопределить toString()
, чтобы добавить эти пробелы, где я говорю.
Я также хочу, чтобы перечисление предоставило правильное перечисление, когда я использую valueOf()
в той же строке, где я добавил пробелы.
Например:
public enum RandomEnum
{
StartHere,
StopHere
}
Вызов toString()
on RandomEnum
, значение которого StartHere
возвращает строку "Start Here"
. Вызов valueOf()
в той же строке ("Start Here"
) возвращает значение перечисления StartHere
.
Как я могу это сделать?
Ответы
Ответ 1
Вы можете попробовать этот код. Поскольку вы не можете переопределить метод valueOf
, вы должны определить собственный метод (getEnum
в примере кода ниже), который возвращает требуемое значение и вместо этого изменит ваш клиент, чтобы использовать этот метод.
public enum RandomEnum {
StartHere("Start Here"),
StopHere("Stop Here");
private String value;
RandomEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return this.getValue();
}
public static RandomEnum getEnum(String value) {
for(RandomEnum v : values())
if(v.getValue().equalsIgnoreCase(value)) return v;
throw new IllegalArgumentException();
}
}
Ответ 2
Попробуйте это, но я не уверен, что будет работать где угодно:)
public enum MyEnum {
A("Start There"),
B("Start Here");
MyEnum(String name) {
try {
Field fieldName = getClass().getSuperclass().getDeclaredField("name");
fieldName.setAccessible(true);
fieldName.set(this, name);
fieldName.setAccessible(false);
} catch (Exception e) {}
}
}
Ответ 3
Вы можете использовать статическую карту в своем перечислении, которая отображает строки для констант перечисления. Используйте его в статическом методе getEnum. Это пропускает необходимость итерации через перечисления каждый раз, когда вы хотите получить один из его значения String.
public enum RandomEnum {
StartHere("Start Here"),
StopHere("Stop Here");
private final String strVal;
private RandomEnum(String strVal) {
this.strVal = strVal;
}
public static RandomEnum getEnum(String strVal) {
if(!strValMap.containsKey(strVal)) {
throw new IllegalArgumentException("Unknown String Value: " + strVal);
}
return strValMap.get(strVal);
}
private static final Map<String, RandomEnum> strValMap;
static {
final Map<String, RandomEnum> tmpMap = Maps.newHashMap();
for(final RandomEnum en : RandomEnum.values()) {
tmpMap.put(en.strVal, en);
}
strValMap = ImmutableMap.copyOf(tmpMap);
}
@Override
public String toString() {
return strVal;
}
}
Просто убедитесь, что статическая инициализация карты происходит ниже объявления констант перечисления.
BTW - тип "ImmutableMap" - это API-интерфейс Google guava, и я определенно рекомендую его в таких случаях.
EDIT - за комментарии:
- Это решение предполагает, что каждое присвоенное строковое значение является уникальным и непустым. Учитывая, что создатель enum может управлять этим, и что строка соответствует уникальному и ненулевому значению перечисления, это кажется безопасным ограничением.
- Я добавил метод toSTring(), заданный в вопросе
Ответ 4
Как насчет реализации Java 8? (нуль может быть заменен вашим Enum по умолчанию)
public static RandomEnum getEnum(String value) {
List<RandomEnum> list = Arrays.asList(RandomEnum.values());
return list.stream().filter(m -> m.value.equals(value)).findAny().orElse(null);
}
Или вы могли бы использовать:
...findAny().orElseThrow(NotFoundException::new);
Ответ 5
Я не думаю, что вы собираетесь работать с valueOf ( "Начать здесь" ).
Но что касается пробелов... попробуйте следующее...
static private enum RandomEnum {
R("Start There"),
G("Start Here");
String value;
RandomEnum(String s) {
value = s;
}
}
System.out.println(RandomEnum.G.value);
System.out.println(RandomEnum.valueOf("G").value);
Start Here
Start Here
Ответ 6
Ниже приведена хорошая универсальная альтернатива valueOf()
public static RandomEnum getEnum(String value) {
for (RandomEnum re : RandomEnum.values()) {
if (re.description.compareTo(value) == 0) {
return re;
}
}
throw new IllegalArgumentException("Invalid RandomEnum value: " + value);
}
Ответ 7
У вас все еще есть возможность реализовать в своем перечислении следующее:
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name){...}