Отображение строки в значение перечисления, как правило, то, что valueOf
статический метод делает для вы.Поэтому, если вы хотите добиться этого с помощью синонимов, вам придется разработать нечто подобное. Однако мы не хотим указывать, что мы можем переопределить статический метод, поэтому для этой цели мы просто назовем его другим: fromString
должен быть уместным.
public enum Language {
ENGLISH("eng", "en", "en_GB", "en_US"),
GERMAN("de", "ge"),
CROATIAN("hr", "cro"),
RUSSIAN("ru"),
BELGIAN("be",";-)");
static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>();
static {
for (Language language:Language.values()) {
// ignoring the case by normalizing to uppercase
ALIAS_MAP.put(language.name().toUpperCase(),language);
for (String alias:language.aliases)
ALIAS_MAP.put(alias.toUpperCase(),language);
}
}
static public boolean has(String value) {
// ignoring the case by normalizing to uppercase
return ALIAS_MAP.containsKey(value.toUpperCase());
}
static public Language fromString(String value) {
if (value == null) throw new NullPointerException("alias null");
Language language = ALIAS_MAP.get(value);
if (language == null)
throw new IllegalArgumentException("Not an alias: "+value);
return language;
}
private List<String> aliases;
private Language(String... aliases) {
this.aliases = Arrays.asList(aliases);
}
}
В пользу этого типа реализации мы можем, как показано, также легко реализовать статический метод has
, чтобы проверить, является ли данный псевдонимом является частью множества значений перечисления. В то же время мы применили несколько хороших соглашений об именах:
- значения перечисления идут в верхнем регистре, чтобы указать, что они находятся в актуальном статическом финале (экземпляры однопользовательского режима).
- в то же время, мы также ставим все остальные статические финалы всех шапок.
Обратите внимание, что мы не должны повторять название самого значения перечисления: мы всегда учитываем это собственное имя автоматически (добавляется к ALIAS_MAP), а сверху нормировать все в верхний регистр, чтобы сделать его чувствительно к регистру ,
Кажется большим, но при использовании перечисления, это выглядит довольно:
public void main() {
Language myLanguage = Language.fromString("en_GB");
if (myLanguage == Language.ENGLISH) {
System.out.println("Yes, I know, you understand English!");
}
}
Подложка контейнер для псевдонимов является Map
, HashMap
быть более конкретными. HashMap
обеспечивает быстрый доступ к псевдонимам, а также легко растет. Всякий раз, когда мы думаем о «индексировании» чего-то, вероятно, наш первый выбор должен быть HashMap
.
Обратите внимание, что для прозрачного использования мы сохраняем как имя самой константы перечисления (полученное методом name()
), так и все псевдонимы. Мы могли бы реализовать это по-другому, сначала попытавшись выполнить поиск, используя встроенный статический метод valueOf
. Это выбор дизайна, но мы бы потенциально иметь дело с дополнительными исключениями и т.д.
I Рекомендуем посмотреть мои статьи: http://java.dzone.com/articles/enum-tricks-customized-valueof и http://java.dzone.com/articles/enum-tricks-hierarchical-data Хотя я не уверен, что понимаю, что вы действительно хотите, я считаю, что хотя бы одна из этих статей содержит ответ на ваш вопрос. – AlexR